From 6081fe49ec15ea8fd0c081aa6a55b0a266755fe7 Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:14:44 -0700 Subject: [PATCH] update shapelib to 1.6.0 (#1257) --- shapelib/{COPYING => LICENSE-LGPL} | 24 +- shapelib/LICENSE-MIT | 21 + shapelib/README.GPSBabel | 2 +- shapelib/dbf_api.html | 46 +- shapelib/dbfopen.c | 2325 +++++++++--------- shapelib/safileio.c | 293 +-- shapelib/shapefil.h | 1028 ++++---- shapelib/shapelib.html | 76 +- shapelib/shp_api.html | 90 +- shapelib/shpopen.c | 3565 ++++++++++++++-------------- 10 files changed, 3505 insertions(+), 3965 deletions(-) rename shapelib/{COPYING => LICENSE-LGPL} (97%) create mode 100644 shapelib/LICENSE-MIT diff --git a/shapelib/COPYING b/shapelib/LICENSE-LGPL similarity index 97% rename from shapelib/COPYING rename to shapelib/LICENSE-LGPL index 0b643ac83..12735e6c2 100644 --- a/shapelib/COPYING +++ b/shapelib/LICENSE-LGPL @@ -1,16 +1,15 @@ - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -100,7 +99,7 @@ works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. - GNU LIBRARY GENERAL PUBLIC LICENSE + GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which @@ -134,7 +133,7 @@ such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. - + 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an @@ -412,7 +411,7 @@ decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. @@ -435,9 +434,9 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS + END OF TERMS AND CONDITIONS - Appendix: How to Apply These Terms to Your New Libraries + How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that @@ -464,8 +463,8 @@ convey the exclusion of warranty; and each file should have at least the Library General Public License for more details. You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. @@ -480,4 +479,3 @@ necessary. Here is a sample; alter the names: Ty Coon, President of Vice That's all there is to it! - diff --git a/shapelib/LICENSE-MIT b/shapelib/LICENSE-MIT new file mode 100644 index 000000000..34fb3422c --- /dev/null +++ b/shapelib/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 1999, Frank Warmerdam + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/shapelib/README.GPSBabel b/shapelib/README.GPSBabel index a3f953509..f5bba78a8 100644 --- a/shapelib/README.GPSBabel +++ b/shapelib/README.GPSBabel @@ -1,4 +1,4 @@ -This is a subset of Shapelib v1.5.0 from http://shapelib.maptools.org/ +This is a subset of Shapelib v1.6.0 from http://shapelib.maptools.org/ The source is unmodified. It's subsetted here only to reduce the amount of size in our tree that it takes and to reduce ongoing diff --git a/shapelib/dbf_api.html b/shapelib/dbf_api.html index 0bd0da1b8..cdd29a22f 100644 --- a/shapelib/dbf_api.html +++ b/shapelib/dbf_api.html @@ -22,13 +22,13 @@ DBFHandle DBFOpen( const char * pszDBFFile, const char * pszAccess ); pszDBFFile: The name of the xBase (.dbf) file to access. pszAccess: The fopen() style access string. At this time only - "rb" (read-only binary) and "rb+" (read/write binary) + "rb" (read-only binary) and "rb+" (read/write binary) should be used. The DBFOpen() function should be used to establish access to an existing - xBase format table file. The returned DBFHandle is passed to other - access functions, and DBFClose() should be invoked to recover resources, and + xBase format table file. The returned DBFHandle is passed to other + access functions, and DBFClose() should be invoked to recover resources, and flush changes to disk when complete. The DBFCreate() function should called to create new xBase files. As a convenience, DBFOpen() can be called with the name of a .shp or .shx file, and it will figure out the @@ -43,8 +43,8 @@ DBFHandle DBFCreate( const char * pszDBFFile ); pszDBFFile: The name of the xBase (.dbf) file to create. - - The DBFCreate() function creates a new xBase format file with the given + + The DBFCreate() function creates a new xBase format file with the given name, and returns an access handle that can be used with other DBF functions. The newly created file will have no fields, and no records. Fields should be added with DBFAddField() before any records add written. @@ -105,19 +105,19 @@ DBFFieldType DBFGetFieldInfo( DBFHandle hDBF, int iField, char * pszFieldName, hDBF: The access handle for the file to be queried, as returned by DBFOpen(), or DBFCreate(). - iField: The field to be queried. This should be a number between + iField: The field to be queried. This should be a number between 0 and n-1, where n is the number fields on the file, as returned by DBFGetFieldCount(). pszFieldName: If this pointer is not NULL the name of the requested field - will be written to this location. The pszFieldName buffer + will be written to this location. The pszFieldName buffer should be at least 12 character is size in order to hold - the longest possible field name of 11 characters plus a + the longest possible field name of 11 characters plus a terminating zero character. pnWidth: If this pointer is not NULL, the width of the requested field will be returned in the int pointed to by pnWidth. This is - the width in characters. + the width in characters. pnDecimals: If this pointer is not NULL, the number of decimal places precision defined for the field will be returned. This is @@ -145,7 +145,7 @@ DBFFieldType DBFGetFieldInfo( DBFHandle hDBF, int iField, char * pszFieldName,
-int DBFAddField( DBFHandle hDBF, const char * pszFieldName,
+int DBFAddField( DBFHandle hDBF, const char * pszFieldName,
DBFFieldType eType, int nWidth, int nDecimals );
hDBF: The access handle for the file to be updated, as returned by
@@ -186,7 +186,7 @@ int DBFAddField( DBFHandle hDBF, const char * pszFieldName,
int DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
-
+
hDBF: The access handle for the file to be queried, as returned by
DBFOpen(), or DBFCreate().
@@ -206,7 +206,7 @@ int DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
double DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
-
+
hDBF: The access handle for the file to be queried, as returned by
DBFOpen(), or DBFCreate().
@@ -226,7 +226,7 @@ double DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
-
+
hDBF: The access handle for the file to be queried, as returned by
DBFOpen(), or DBFCreate().
@@ -237,10 +237,10 @@ const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
The DBFReadStringAttribute() will read the value of one field and return
- it as a string. This function may be used on any field type (including
+ it as a string. This function may be used on any field type (including
FTInteger and FTDouble) and will return the string representation stored
in the .dbf file. The returned pointer is to an internal buffer
- which is only valid untill the next DBF function call. It's contents may
+ which is only valid until the next DBF function call. It's contents may
be copied with normal string functions such as strcpy(), or strdup(). If
the TRIM_DBF_WHITESPACE macro is defined in shapefil.h (it is by default)
then all leading and trailing space (ASCII 32) characters will be stripped
@@ -252,7 +252,7 @@ const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
int DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
-
+
hDBF: The access handle for the file to be queried, as returned by
DBFOpen(), or DBFCreate().
@@ -265,7 +265,7 @@ int DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
This function will return TRUE if the indicated field is NULL valued
otherwise FALSE. Note that NULL fields are represented in the .dbf file
as having all spaces in the field. Reading NULL fields will result in
- a value of 0.0 or an empty string with the other DBFRead*Attribute()
+ a value of 0.0 or an empty string with the other DBFRead*Attribute()
functions.
@@ -289,7 +289,7 @@ int DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField,
The DBFWriteIntegerAttribute() function is used to write a value to a numeric
field (FTInteger, or FTDouble). If the write succeeds the value TRUE will
-be returned, otherwise FALSE will be returned. If the value is too large to
+be returned, otherwise FALSE will be returned. If the value is too large to
fit in the field, it will be truncated and FALSE returned.
@@ -313,7 +313,7 @@ int DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
The DBFWriteDoubleAttribute() function is used to write a value to a numeric
field (FTInteger, or FTDouble). If the write succeeds the value TRUE will
-be returned, otherwise FALSE will be returned. If the value is too large to
+be returned, otherwise FALSE will be returned. If the value is too large to
fit in the field, it will be truncated and FALSE returned.
@@ -336,8 +336,8 @@ int DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
The DBFWriteStringAttribute() function is used to write a value to a string
-field (FString). If the write succeeds the value TRUE willbe returned,
-otherwise FALSE will be returned. If the value is too large to
+field (FString). If the write succeeds the value TRUE willbe returned,
+otherwise FALSE will be returned. If the value is too large to
fit in the field, it will be truncated and FALSE returned.
@@ -358,7 +358,7 @@ int DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );
The DBFWriteNULLAttribute() function is used to clear the indicated field
to a NULL value. In the .dbf file this is represented by setting the entire
-field to spaces. If the write succeeds the value TRUE willbe returned,
+field to spaces. If the write succeeds the value TRUE willbe returned,
otherwise FALSE will be returned.
@@ -414,7 +414,7 @@ char DBFGetNativeFieldType( DBFHandle hDBF, int iField );
hDBF: The access handle for the file.
iField: The field index to query.
-
+
This function returns the DBF type code of the indicated field. It will
diff --git a/shapelib/dbfopen.c b/shapelib/dbfopen.c
index 218db70cf..ee5be97f0 100644
--- a/shapelib/dbfopen.c
+++ b/shapelib/dbfopen.c
@@ -1,5 +1,4 @@
/******************************************************************************
- * $Id: dbfopen.c,v 1.94 2018-08-16 15:39:07 erouault Exp $
*
* Project: Shapelib
* Purpose: Implementation of .dbf access API documented in dbf_api.html.
@@ -7,199 +6,16 @@
*
******************************************************************************
* Copyright (c) 1999, Frank Warmerdam
- * Copyright (c) 2012-2013, Even Rouault
+ * Copyright (c) 2012-2019, Even Rouault
*
- * This software is available under the following "MIT Style" license,
- * or at the option of the licensee under the LGPL (see COPYING). This
- * option is discussed in more detail in shapelib.html.
- *
- * --
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ******************************************************************************
- *
- * $Log: dbfopen.c,v $
- * Revision 1.94 2018-08-16 15:39:07 erouault
- * * shpopen.c, dbfopen.c, shptree.c, sbnsearch.c: resyc with GDAL
- * internal shapelib. Mostly to allow building those files as C++
- * without warning. Also add FTDate entry in DBFFieldType
- * (see https://github.com/OSGeo/gdal/pull/308). And some other
- * code cleanups
- *
- * Revision 1.93 2018-08-16 15:24:46 erouault
- * * dbfopen.c: fix a bug where the end of file character was
- * written on top of the first character of the first field name
- * when deleting a field on a .dbf without records.
- * Fixes https://github.com/OSGeo/gdal/issues/863
- *
- * Revision 1.92 2016-12-05 18:44:08 erouault
- * * dbfopen.c, shapefil.h: write DBF end-of-file character 0x1A by default.
- * This behaviour can be controlled with the DBFSetWriteEndOfFileChar()
- * function.
- *
- * Revision 1.91 2016-12-05 12:44:05 erouault
- * * Major overhaul of Makefile build system to use autoconf/automake.
- *
- * * Warning fixes in contrib/
- *
- * Revision 1.90 2016-12-04 15:30:15 erouault
- * * shpopen.c, dbfopen.c, shptree.c, shapefil.h: resync with
- * GDAL Shapefile driver. Mostly cleanups. SHPObject and DBFInfo
- * structures extended with new members. New functions:
- * DBFSetLastModifiedDate, SHPOpenLLEx, SHPRestoreSHX,
- * SHPSetFastModeReadObject
- *
- * * sbnsearch.c: new file to implement original ESRI .sbn spatial
- * index reading. (no write support). New functions:
- * SBNOpenDiskTree, SBNCloseDiskTree, SBNSearchDiskTree,
- * SBNSearchDiskTreeInteger, SBNSearchFreeIds
- *
- * * Makefile, makefile.vc, CMakeLists.txt, shapelib.def: updates
- * with new file and symbols.
- *
- * * commit: helper script to cvs commit
- *
- * Revision 1.89 2011-07-24 05:59:25 fwarmerdam
- * minimize use of CPLError in favor of SAHooks.Error()
- *
- * Revision 1.88 2011-05-13 17:35:17 fwarmerdam
- * added DBFReorderFields() and DBFAlterFields() functions (from Even)
- *
- * Revision 1.87 2011-05-07 22:41:02 fwarmerdam
- * ensure pending record is flushed when adding a native field (GDAL #4073)
- *
- * Revision 1.86 2011-04-17 15:15:29 fwarmerdam
- * Removed unused variable.
- *
- * Revision 1.85 2010-12-06 16:09:34 fwarmerdam
- * fix buffer read overrun fetching code page (bug 2276)
- *
- * Revision 1.84 2009-10-29 19:59:48 fwarmerdam
- * avoid crash on truncated header (gdal #3093)
- *
- * Revision 1.83 2008/11/12 14:28:15 fwarmerdam
- * DBFCreateField() now works on files with records
- *
- * Revision 1.82 2008/11/11 17:47:09 fwarmerdam
- * added DBFDeleteField() function
- *
- * Revision 1.81 2008/01/03 17:48:13 bram
- * in DBFCreate, use default code page LDID/87 (= 0x57, ANSI)
- * instead of LDID/3. This seems to be the same as what ESRI
- * would be doing by default.
- *
- * Revision 1.80 2007/12/30 14:36:39 fwarmerdam
- * avoid syntax issue with last comment.
- *
- * Revision 1.79 2007/12/30 14:35:48 fwarmerdam
- * Avoid char* / unsigned char* warnings.
- *
- * Revision 1.78 2007/12/18 18:28:07 bram
- * - create hook for client specific atof (bugzilla ticket 1615)
- * - check for NULL handle before closing cpCPG file, and close after reading.
- *
- * Revision 1.77 2007/12/15 20:25:21 bram
- * dbfopen.c now reads the Code Page information from the DBF file, and exports
- * this information as a string through the DBFGetCodePage function. This is
- * either the number from the LDID header field ("LDID/") or as the
- * content of an accompanying .CPG file. When creating a DBF file, the code can
- * be set using DBFCreateEx.
- *
- * Revision 1.76 2007/12/12 22:21:32 bram
- * DBFClose: check for NULL psDBF handle before trying to close it.
- *
- * Revision 1.75 2007/12/06 13:58:19 fwarmerdam
- * make sure file offset calculations are done in as SAOffset
- *
- * Revision 1.74 2007/12/06 07:00:25 fwarmerdam
- * dbfopen now using SAHooks for fileio
- *
- * Revision 1.73 2007/09/03 19:48:11 fwarmerdam
- * move DBFReadAttribute() static dDoubleField into dbfinfo
- *
- * Revision 1.72 2007/09/03 19:34:06 fwarmerdam
- * Avoid use of static tuple buffer in DBFReadTuple()
- *
- * Revision 1.71 2006/06/22 14:37:18 fwarmerdam
- * avoid memory leak if dbfopen fread fails
- *
- * Revision 1.70 2006/06/17 17:47:05 fwarmerdam
- * use calloc() for dbfinfo in DBFCreate
- *
- * Revision 1.69 2006/06/17 15:34:32 fwarmerdam
- * disallow creating fields wider than 255
- *
- * Revision 1.68 2006/06/17 15:12:40 fwarmerdam
- * Fixed C++ style comments.
- *
- * Revision 1.67 2006/06/17 00:24:53 fwarmerdam
- * Don't treat non-zero decimals values as high order byte for length
- * for strings. It causes serious corruption for some files.
- * http://bugzilla.remotesensing.org/show_bug.cgi?id=1202
- *
- * Revision 1.66 2006/03/29 18:26:20 fwarmerdam
- * fixed bug with size of pachfieldtype in dbfcloneempty
- *
- * Revision 1.65 2006/02/15 01:14:30 fwarmerdam
- * added DBFAddNativeFieldType
- *
- * Revision 1.64 2006/02/09 00:29:04 fwarmerdam
- * Changed to put spaces into string fields that are NULL as
- * per http://bugzilla.maptools.org/show_bug.cgi?id=316.
- *
- * Revision 1.63 2006/01/25 15:35:43 fwarmerdam
- * check success on DBFFlushRecord
- *
- * Revision 1.62 2006/01/10 16:28:03 fwarmerdam
- * Fixed typo in CPLError.
- *
- * Revision 1.61 2006/01/10 16:26:29 fwarmerdam
- * Push loading record buffer into DBFLoadRecord.
- * Implement CPL error reporting if USE_CPL defined.
- *
- * Revision 1.60 2006/01/05 01:27:27 fwarmerdam
- * added dbf deletion mark/fetch
- *
- * Revision 1.59 2005/03/14 15:20:28 fwarmerdam
- * Fixed last change.
- *
- * Revision 1.58 2005/03/14 15:18:54 fwarmerdam
- * Treat very wide fields with no decimals as double. This is
- * more than 32bit integer fields.
- *
- * Revision 1.57 2005/02/10 20:16:54 fwarmerdam
- * Make the pszStringField buffer for DBFReadAttribute() static char [256]
- * as per bug 306.
- *
- * Revision 1.56 2005/02/10 20:07:56 fwarmerdam
- * Fixed bug 305 in DBFCloneEmpty() - header length problem.
- *
- * Revision 1.55 2004/09/26 20:23:46 fwarmerdam
- * avoid warnings with rcsid and signed/unsigned stuff
- *
- * Revision 1.54 2004/09/15 16:26:10 fwarmerdam
- * Treat all blank numeric fields as null too.
- */
+ * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+ ******************************************************************************/
#include "shapefil.h"
#include
+#include
+#include
#include
#include
#include
@@ -208,76 +24,62 @@
#include "cpl_string.h"
#else
-#if defined(WIN32) || defined(_WIN32)
-# define STRCASECMP(a,b) (stricmp(a,b))
-# else
+#if defined(_MSC_VER)
+#define STRCASECMP(a, b) (_stricmp(a, b))
+#elif defined(WIN32) || defined(_WIN32)
+#define STRCASECMP(a, b) (stricmp(a, b))
+#else
#include
-# define STRCASECMP(a,b) (strcasecmp(a,b))
+#define STRCASECMP(a, b) (strcasecmp(a, b))
#endif
#if defined(_MSC_VER)
-# if _MSC_VER < 1900
-# define snprintf _snprintf
-# endif
+#if _MSC_VER < 1900
+#define snprintf _snprintf
+#endif
#elif defined(WIN32) || defined(_WIN32)
-# ifndef snprintf
-# define snprintf _snprintf
-# endif
+#ifndef snprintf
+#define snprintf _snprintf
+#endif
#endif
#define CPLsprintf sprintf
#define CPLsnprintf snprintf
#endif
-SHP_CVSID("$Id: dbfopen.c,v 1.94 2018-08-16 15:39:07 erouault Exp $")
-
#ifndef FALSE
-# define FALSE 0
-# define TRUE 1
+#define FALSE 0
+#define TRUE 1
#endif
/* File header size */
-#define XBASE_FILEHDR_SZ 32
+#define XBASE_FILEHDR_SZ 32
#define HEADER_RECORD_TERMINATOR 0x0D
/* See http://www.manmrk.net/tutorials/database/xbase/dbf.html */
-#define END_OF_FILE_CHARACTER 0x1A
+#define END_OF_FILE_CHARACTER 0x1A
#ifdef USE_CPL
-CPL_INLINE static void CPL_IGNORE_RET_VAL_INT(CPL_UNUSED int unused) {}
+CPL_INLINE static void CPL_IGNORE_RET_VAL_INT(CPL_UNUSED int unused)
+{
+}
#else
#define CPL_IGNORE_RET_VAL_INT(x) x
#endif
#ifdef __cplusplus
-#define STATIC_CAST(type,x) static_cast(x)
-#define REINTERPRET_CAST(type,x) reinterpret_cast(x)
-#define CONST_CAST(type,x) const_cast(x)
+#define STATIC_CAST(type, x) static_cast(x)
+#define REINTERPRET_CAST(type, x) reinterpret_cast(x)
+#define CONST_CAST(type, x) const_cast(x)
#define SHPLIB_NULLPTR nullptr
#else
-#define STATIC_CAST(type,x) ((type)(x))
-#define REINTERPRET_CAST(type,x) ((type)(x))
-#define CONST_CAST(type,x) ((type)(x))
+#define STATIC_CAST(type, x) ((type)(x))
+#define REINTERPRET_CAST(type, x) ((type)(x))
+#define CONST_CAST(type, x) ((type)(x))
#define SHPLIB_NULLPTR NULL
#endif
-/************************************************************************/
-/* SfRealloc() */
-/* */
-/* A realloc cover function that will access a NULL pointer as */
-/* a valid input. */
-/************************************************************************/
-
-static void * SfRealloc( void * pMem, int nNewSize )
-
-{
- if( pMem == SHPLIB_NULLPTR )
- return malloc(nNewSize);
- else
- return realloc(pMem,nNewSize);
-}
-
/************************************************************************/
/* DBFWriteHeader() */
/* */
@@ -288,19 +90,18 @@ static void * SfRealloc( void * pMem, int nNewSize )
/************************************************************************/
static void DBFWriteHeader(DBFHandle psDBF)
-
{
- unsigned char abyHeader[XBASE_FILEHDR_SZ] = { 0 };
+ unsigned char abyHeader[XBASE_FILEHDR_SZ] = {0};
- if( !psDBF->bNoHeader )
+ if (!psDBF->bNoHeader)
return;
psDBF->bNoHeader = FALSE;
-/* -------------------------------------------------------------------- */
-/* Initialize the file header information. */
-/* -------------------------------------------------------------------- */
- abyHeader[0] = 0x03; /* memo field? - just copying */
+ /* -------------------------------------------------------------------- */
+ /* Initialize the file header information. */
+ /* -------------------------------------------------------------------- */
+ abyHeader[0] = 0x03; /* memo field? - just copying */
/* write out update date */
abyHeader[1] = STATIC_CAST(unsigned char, psDBF->nUpdateYearSince1900);
@@ -317,35 +118,33 @@ static void DBFWriteHeader(DBFHandle psDBF)
abyHeader[29] = STATIC_CAST(unsigned char, psDBF->iLanguageDriver);
-/* -------------------------------------------------------------------- */
-/* Write the initial 32 byte file header, and all the field */
-/* descriptions. */
-/* -------------------------------------------------------------------- */
- psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
- psDBF->sHooks.FWrite( abyHeader, XBASE_FILEHDR_SZ, 1, psDBF->fp );
- psDBF->sHooks.FWrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields,
- psDBF->fp );
-
-/* -------------------------------------------------------------------- */
-/* Write out the newline character if there is room for it. */
-/* -------------------------------------------------------------------- */
- if( psDBF->nHeaderLength > XBASE_FLDHDR_SZ*psDBF->nFields +
- XBASE_FLDHDR_SZ )
+ /* -------------------------------------------------------------------- */
+ /* Write the initial 32 byte file header, and all the field */
+ /* descriptions. */
+ /* -------------------------------------------------------------------- */
+ psDBF->sHooks.FSeek(psDBF->fp, 0, 0);
+ psDBF->sHooks.FWrite(abyHeader, XBASE_FILEHDR_SZ, 1, psDBF->fp);
+ psDBF->sHooks.FWrite(psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields,
+ psDBF->fp);
+
+ /* -------------------------------------------------------------------- */
+ /* Write out the newline character if there is room for it. */
+ /* -------------------------------------------------------------------- */
+ if (psDBF->nHeaderLength >
+ XBASE_FLDHDR_SZ * psDBF->nFields + XBASE_FLDHDR_SZ)
{
- char cNewline;
-
- cNewline = HEADER_RECORD_TERMINATOR;
- psDBF->sHooks.FWrite( &cNewline, 1, 1, psDBF->fp );
+ char cNewline = HEADER_RECORD_TERMINATOR;
+ psDBF->sHooks.FWrite(&cNewline, 1, 1, psDBF->fp);
}
-/* -------------------------------------------------------------------- */
-/* If the file is new, add a EOF character. */
-/* -------------------------------------------------------------------- */
- if( psDBF->nRecords == 0 && psDBF->bWriteEndOfFileChar )
+ /* -------------------------------------------------------------------- */
+ /* If the file is new, add a EOF character. */
+ /* -------------------------------------------------------------------- */
+ if (psDBF->nRecords == 0 && psDBF->bWriteEndOfFileChar)
{
char ch = END_OF_FILE_CHARACTER;
- psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp );
+ psDBF->sHooks.FWrite(&ch, 1, 1, psDBF->fp);
}
}
@@ -355,125 +154,149 @@ static void DBFWriteHeader(DBFHandle psDBF)
/* Write out the current record if there is one. */
/************************************************************************/
-static int DBFFlushRecord( DBFHandle psDBF )
-
+static bool DBFFlushRecord(DBFHandle psDBF)
{
- SAOffset nRecordOffset;
-
- if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
+ if (psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1)
{
- psDBF->bCurrentRecordModified = FALSE;
-
- nRecordOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset, psDBF->nCurrentRecord)
- + psDBF->nHeaderLength;
+ psDBF->bCurrentRecordModified = FALSE;
+
+ const SAOffset nRecordOffset =
+ psDBF->nRecordLength *
+ STATIC_CAST(SAOffset, psDBF->nCurrentRecord) +
+ psDBF->nHeaderLength;
+
+ /* -------------------------------------------------------------------- */
+ /* Guard FSeek with check for whether we're already at position; */
+ /* no-op FSeeks defeat network filesystems' write buffering. */
+ /* -------------------------------------------------------------------- */
+ if (psDBF->bRequireNextWriteSeek ||
+ psDBF->sHooks.FTell(psDBF->fp) != nRecordOffset)
+ {
+ if (psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0) != 0)
+ {
+ char szMessage[128];
+ snprintf(
+ szMessage, sizeof(szMessage),
+ "Failure seeking to position before writing DBF record %d.",
+ psDBF->nCurrentRecord);
+ psDBF->sHooks.Error(szMessage);
+ return false;
+ }
+ }
- if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ) != 0
- || psDBF->sHooks.FWrite( psDBF->pszCurrentRecord,
- psDBF->nRecordLength,
- 1, psDBF->fp ) != 1 )
+ if (psDBF->sHooks.FWrite(psDBF->pszCurrentRecord, psDBF->nRecordLength,
+ 1, psDBF->fp) != 1)
{
char szMessage[128];
- snprintf( szMessage, sizeof(szMessage), "Failure writing DBF record %d.",
- psDBF->nCurrentRecord );
- psDBF->sHooks.Error( szMessage );
- return FALSE;
+ snprintf(szMessage, sizeof(szMessage),
+ "Failure writing DBF record %d.", psDBF->nCurrentRecord);
+ psDBF->sHooks.Error(szMessage);
+ return false;
}
- if( psDBF->nCurrentRecord == psDBF->nRecords - 1 )
+ /* -------------------------------------------------------------------- */
+ /* If next op is also a write, allow possible skipping of FSeek. */
+ /* -------------------------------------------------------------------- */
+ psDBF->bRequireNextWriteSeek = FALSE;
+
+ if (psDBF->nCurrentRecord == psDBF->nRecords - 1)
{
- if( psDBF->bWriteEndOfFileChar )
+ if (psDBF->bWriteEndOfFileChar)
{
char ch = END_OF_FILE_CHARACTER;
- psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp );
+ psDBF->sHooks.FWrite(&ch, 1, 1, psDBF->fp);
}
}
}
- return TRUE;
+ return true;
}
/************************************************************************/
/* DBFLoadRecord() */
/************************************************************************/
-static int DBFLoadRecord( DBFHandle psDBF, int iRecord )
-
+static bool DBFLoadRecord(DBFHandle psDBF, int iRecord)
{
- if( psDBF->nCurrentRecord != iRecord )
+ if (psDBF->nCurrentRecord != iRecord)
{
- SAOffset nRecordOffset;
+ if (!DBFFlushRecord(psDBF))
+ return false;
- if( !DBFFlushRecord( psDBF ) )
- return FALSE;
-
- nRecordOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength;
+ const SAOffset nRecordOffset =
+ psDBF->nRecordLength * STATIC_CAST(SAOffset, iRecord) +
+ psDBF->nHeaderLength;
- if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, SEEK_SET ) != 0 )
+ if (psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, SEEK_SET) != 0)
{
char szMessage[128];
- snprintf( szMessage, sizeof(szMessage), "fseek(%ld) failed on DBF file.",
- STATIC_CAST(long, nRecordOffset) );
- psDBF->sHooks.Error( szMessage );
- return FALSE;
+ snprintf(szMessage, sizeof(szMessage),
+ "fseek(%ld) failed on DBF file.",
+ STATIC_CAST(long, nRecordOffset));
+ psDBF->sHooks.Error(szMessage);
+ return false;
}
- if( psDBF->sHooks.FRead( psDBF->pszCurrentRecord,
- psDBF->nRecordLength, 1, psDBF->fp ) != 1 )
+ if (psDBF->sHooks.FRead(psDBF->pszCurrentRecord, psDBF->nRecordLength,
+ 1, psDBF->fp) != 1)
{
char szMessage[128];
- snprintf( szMessage, sizeof(szMessage), "fread(%d) failed on DBF file.",
- psDBF->nRecordLength );
- psDBF->sHooks.Error( szMessage );
- return FALSE;
+ snprintf(szMessage, sizeof(szMessage),
+ "fread(%d) failed on DBF file.", psDBF->nRecordLength);
+ psDBF->sHooks.Error(szMessage);
+ return false;
}
- psDBF->nCurrentRecord = iRecord;
+ psDBF->nCurrentRecord = iRecord;
+ /* -------------------------------------------------------------------- */
+ /* Require a seek for next write in case of mixed R/W operations. */
+ /* -------------------------------------------------------------------- */
+ psDBF->bRequireNextWriteSeek = TRUE;
}
- return TRUE;
+ return true;
}
/************************************************************************/
/* DBFUpdateHeader() */
/************************************************************************/
-void SHPAPI_CALL
-DBFUpdateHeader( DBFHandle psDBF )
-
+void SHPAPI_CALL DBFUpdateHeader(DBFHandle psDBF)
{
- unsigned char abyFileHeader[XBASE_FILEHDR_SZ];
-
- if( psDBF->bNoHeader )
- DBFWriteHeader( psDBF );
+ if (psDBF->bNoHeader)
+ DBFWriteHeader(psDBF);
- if( !DBFFlushRecord( psDBF ) )
+ if (!DBFFlushRecord(psDBF))
return;
- psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
- psDBF->sHooks.FRead( abyFileHeader, sizeof(abyFileHeader), 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, 0, 0);
+
+ unsigned char abyFileHeader[XBASE_FILEHDR_SZ] = {0};
+ psDBF->sHooks.FRead(abyFileHeader, 1, sizeof(abyFileHeader), psDBF->fp);
abyFileHeader[1] = STATIC_CAST(unsigned char, psDBF->nUpdateYearSince1900);
abyFileHeader[2] = STATIC_CAST(unsigned char, psDBF->nUpdateMonth);
abyFileHeader[3] = STATIC_CAST(unsigned char, psDBF->nUpdateDay);
abyFileHeader[4] = STATIC_CAST(unsigned char, psDBF->nRecords & 0xFF);
- abyFileHeader[5] = STATIC_CAST(unsigned char, (psDBF->nRecords>>8) & 0xFF);
- abyFileHeader[6] = STATIC_CAST(unsigned char, (psDBF->nRecords>>16) & 0xFF);
- abyFileHeader[7] = STATIC_CAST(unsigned char, (psDBF->nRecords>>24) & 0xFF);
+ abyFileHeader[5] =
+ STATIC_CAST(unsigned char, (psDBF->nRecords >> 8) & 0xFF);
+ abyFileHeader[6] =
+ STATIC_CAST(unsigned char, (psDBF->nRecords >> 16) & 0xFF);
+ abyFileHeader[7] =
+ STATIC_CAST(unsigned char, (psDBF->nRecords >> 24) & 0xFF);
- psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
- psDBF->sHooks.FWrite( abyFileHeader, sizeof(abyFileHeader), 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, 0, 0);
+ psDBF->sHooks.FWrite(abyFileHeader, sizeof(abyFileHeader), 1, psDBF->fp);
- psDBF->sHooks.FFlush( psDBF->fp );
+ psDBF->sHooks.FFlush(psDBF->fp);
}
/************************************************************************/
/* DBFSetLastModifiedDate() */
/************************************************************************/
-void SHPAPI_CALL
-DBFSetLastModifiedDate( DBFHandle psDBF, int nYYSince1900, int nMM, int nDD )
+void SHPAPI_CALL DBFSetLastModifiedDate(DBFHandle psDBF, int nYYSince1900,
+ int nMM, int nDD)
{
psDBF->nUpdateYearSince1900 = nYYSince1900;
psDBF->nUpdateMonth = nMM;
@@ -486,30 +309,27 @@ DBFSetLastModifiedDate( DBFHandle psDBF, int nYYSince1900, int nMM, int nDD )
/* Open a .dbf file. */
/************************************************************************/
-DBFHandle SHPAPI_CALL
-DBFOpen( const char * pszFilename, const char * pszAccess )
+DBFHandle SHPAPI_CALL DBFOpen(const char *pszFilename, const char *pszAccess)
{
SAHooks sHooks;
- SASetupDefaultHooks( &sHooks );
+ SASetupDefaultHooks(&sHooks);
- return DBFOpenLL( pszFilename, pszAccess, &sHooks );
+ return DBFOpenLL(pszFilename, pszAccess, &sHooks);
}
/************************************************************************/
/* DBFGetLenWithoutExtension() */
/************************************************************************/
-static int DBFGetLenWithoutExtension(const char* pszBasename)
+static int DBFGetLenWithoutExtension(const char *pszBasename)
{
- int i;
- int nLen = STATIC_CAST(int, strlen(pszBasename));
- for( i = nLen-1;
- i > 0 && pszBasename[i] != '/' && pszBasename[i] != '\\';
- i-- )
+ const int nLen = STATIC_CAST(int, strlen(pszBasename));
+ for (int i = nLen - 1;
+ i > 0 && pszBasename[i] != '/' && pszBasename[i] != '\\'; i--)
{
- if( pszBasename[i] == '.' )
+ if (pszBasename[i] == '.')
{
return i;
}
@@ -523,65 +343,58 @@ static int DBFGetLenWithoutExtension(const char* pszBasename)
/* Open a .dbf file. */
/************************************************************************/
-DBFHandle SHPAPI_CALL
-DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks )
-
+DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess,
+ const SAHooks *psHooks)
{
- DBFHandle psDBF;
- SAFile pfCPG;
- unsigned char *pabyBuf;
- int nFields, nHeadLen, iField;
- char *pszFullname;
- int nBufSize = 500;
- int nLenWithoutExtension;
-
-/* -------------------------------------------------------------------- */
-/* We only allow the access strings "rb" and "r+". */
-/* -------------------------------------------------------------------- */
- if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0
- && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0
- && strcmp(pszAccess,"r+b") != 0 )
+ /* -------------------------------------------------------------------- */
+ /* We only allow the access strings "rb" and "r+". */
+ /* -------------------------------------------------------------------- */
+ if (strcmp(pszAccess, "r") != 0 && strcmp(pszAccess, "r+") != 0 &&
+ strcmp(pszAccess, "rb") != 0 && strcmp(pszAccess, "rb+") != 0 &&
+ strcmp(pszAccess, "r+b") != 0)
return SHPLIB_NULLPTR;
- if( strcmp(pszAccess,"r") == 0 )
+ if (strcmp(pszAccess, "r") == 0)
pszAccess = "rb";
- if( strcmp(pszAccess,"r+") == 0 )
+ if (strcmp(pszAccess, "r+") == 0)
pszAccess = "rb+";
-/* -------------------------------------------------------------------- */
-/* Compute the base (layer) name. If there is any extension */
-/* on the passed in filename we will strip it off. */
-/* -------------------------------------------------------------------- */
- nLenWithoutExtension = DBFGetLenWithoutExtension(pszFilename);
- pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5));
+ /* -------------------------------------------------------------------- */
+ /* Compute the base (layer) name. If there is any extension */
+ /* on the passed in filename we will strip it off. */
+ /* -------------------------------------------------------------------- */
+ const int nLenWithoutExtension = DBFGetLenWithoutExtension(pszFilename);
+ char *pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5));
memcpy(pszFullname, pszFilename, nLenWithoutExtension);
memcpy(pszFullname + nLenWithoutExtension, ".dbf", 5);
- psDBF = STATIC_CAST(DBFHandle, calloc( 1, sizeof(DBFInfo) ));
- psDBF->fp = psHooks->FOpen( pszFullname, pszAccess );
- memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
+ DBFHandle psDBF = STATIC_CAST(DBFHandle, calloc(1, sizeof(DBFInfo)));
+ psDBF->fp = psHooks->FOpen(pszFullname, pszAccess, psHooks->pvUserData);
+ memcpy(&(psDBF->sHooks), psHooks, sizeof(SAHooks));
- if( psDBF->fp == SHPLIB_NULLPTR )
+ if (psDBF->fp == SHPLIB_NULLPTR)
{
memcpy(pszFullname + nLenWithoutExtension, ".DBF", 5);
- psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
+ psDBF->fp =
+ psDBF->sHooks.FOpen(pszFullname, pszAccess, psHooks->pvUserData);
}
memcpy(pszFullname + nLenWithoutExtension, ".cpg", 5);
- pfCPG = psHooks->FOpen( pszFullname, "r" );
- if( pfCPG == SHPLIB_NULLPTR )
+ SAFile pfCPG = psHooks->FOpen(pszFullname, "r", psHooks->pvUserData);
+ if (pfCPG == SHPLIB_NULLPTR)
{
memcpy(pszFullname + nLenWithoutExtension, ".CPG", 5);
- pfCPG = psHooks->FOpen( pszFullname, "r" );
+ pfCPG = psHooks->FOpen(pszFullname, "r", psHooks->pvUserData);
}
- free( pszFullname );
+ free(pszFullname);
- if( psDBF->fp == SHPLIB_NULLPTR )
+ if (psDBF->fp == SHPLIB_NULLPTR)
{
- free( psDBF );
- if( pfCPG ) psHooks->FClose( pfCPG );
+ free(psDBF);
+ if (pfCPG)
+ psHooks->FClose(pfCPG);
return SHPLIB_NULLPTR;
}
@@ -589,84 +402,88 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks )
psDBF->nCurrentRecord = -1;
psDBF->bCurrentRecordModified = FALSE;
-/* -------------------------------------------------------------------- */
-/* Read Table Header info */
-/* -------------------------------------------------------------------- */
- pabyBuf = STATIC_CAST(unsigned char *, malloc(nBufSize));
- if( psDBF->sHooks.FRead( pabyBuf, XBASE_FILEHDR_SZ, 1, psDBF->fp ) != 1 )
+ /* -------------------------------------------------------------------- */
+ /* Read Table Header info */
+ /* -------------------------------------------------------------------- */
+ const int nBufSize = 500;
+ unsigned char *pabyBuf = STATIC_CAST(unsigned char *, malloc(nBufSize));
+ if (psDBF->sHooks.FRead(pabyBuf, XBASE_FILEHDR_SZ, 1, psDBF->fp) != 1)
{
- psDBF->sHooks.FClose( psDBF->fp );
- if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
- free( pabyBuf );
- free( psDBF );
+ psDBF->sHooks.FClose(psDBF->fp);
+ if (pfCPG)
+ psDBF->sHooks.FClose(pfCPG);
+ free(pabyBuf);
+ free(psDBF);
return SHPLIB_NULLPTR;
}
DBFSetLastModifiedDate(psDBF, pabyBuf[1], pabyBuf[2], pabyBuf[3]);
- psDBF->nRecords =
- pabyBuf[4]|(pabyBuf[5]<<8)|(pabyBuf[6]<<16)|((pabyBuf[7]&0x7f)<<24);
+ psDBF->nRecords = pabyBuf[4] | (pabyBuf[5] << 8) | (pabyBuf[6] << 16) |
+ ((pabyBuf[7] & 0x7f) << 24);
- psDBF->nHeaderLength = nHeadLen = pabyBuf[8]|(pabyBuf[9]<<8);
- psDBF->nRecordLength = pabyBuf[10]|(pabyBuf[11]<<8);
+ const int nHeadLen = pabyBuf[8] | (pabyBuf[9] << 8);
+ psDBF->nHeaderLength = nHeadLen;
+ psDBF->nRecordLength = pabyBuf[10] | (pabyBuf[11] << 8);
psDBF->iLanguageDriver = pabyBuf[29];
if (psDBF->nRecordLength == 0 || nHeadLen < XBASE_FILEHDR_SZ)
{
- psDBF->sHooks.FClose( psDBF->fp );
- if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
- free( pabyBuf );
- free( psDBF );
+ psDBF->sHooks.FClose(psDBF->fp);
+ if (pfCPG)
+ psDBF->sHooks.FClose(pfCPG);
+ free(pabyBuf);
+ free(psDBF);
return SHPLIB_NULLPTR;
}
- psDBF->nFields = nFields = (nHeadLen - XBASE_FILEHDR_SZ) / XBASE_FLDHDR_SZ;
+ const int nFields = (nHeadLen - XBASE_FILEHDR_SZ) / XBASE_FLDHDR_SZ;
+ psDBF->nFields = nFields;
/* coverity[tainted_data] */
psDBF->pszCurrentRecord = STATIC_CAST(char *, malloc(psDBF->nRecordLength));
-/* -------------------------------------------------------------------- */
-/* Figure out the code page from the LDID and CPG */
-/* -------------------------------------------------------------------- */
-
+ /* -------------------------------------------------------------------- */
+ /* Figure out the code page from the LDID and CPG */
+ /* -------------------------------------------------------------------- */
psDBF->pszCodePage = SHPLIB_NULLPTR;
- if( pfCPG )
+ if (pfCPG)
{
- size_t n;
- memset( pabyBuf, 0, nBufSize);
- psDBF->sHooks.FRead( pabyBuf, nBufSize - 1, 1, pfCPG );
- n = strcspn( REINTERPRET_CAST(char *, pabyBuf), "\n\r" );
- if( n > 0 )
+ memset(pabyBuf, 0, nBufSize);
+ psDBF->sHooks.FRead(pabyBuf, 1, nBufSize - 1, pfCPG);
+ const size_t n = strcspn(REINTERPRET_CAST(char *, pabyBuf), "\n\r");
+ if (n > 0)
{
pabyBuf[n] = '\0';
psDBF->pszCodePage = STATIC_CAST(char *, malloc(n + 1));
- memcpy( psDBF->pszCodePage, pabyBuf, n + 1 );
+ memcpy(psDBF->pszCodePage, pabyBuf, n + 1);
}
- psDBF->sHooks.FClose( pfCPG );
+ psDBF->sHooks.FClose(pfCPG);
}
- if( psDBF->pszCodePage == SHPLIB_NULLPTR && pabyBuf[29] != 0 )
+ if (psDBF->pszCodePage == SHPLIB_NULLPTR && pabyBuf[29] != 0)
{
- snprintf( REINTERPRET_CAST(char *, pabyBuf), nBufSize, "LDID/%d", psDBF->iLanguageDriver );
- psDBF->pszCodePage = STATIC_CAST(char *, malloc(strlen(REINTERPRET_CAST(char*, pabyBuf)) + 1));
- strcpy( psDBF->pszCodePage, REINTERPRET_CAST(char *, pabyBuf) );
+ snprintf(REINTERPRET_CAST(char *, pabyBuf), nBufSize, "LDID/%d",
+ psDBF->iLanguageDriver);
+ psDBF->pszCodePage = STATIC_CAST(
+ char *, malloc(strlen(REINTERPRET_CAST(char *, pabyBuf)) + 1));
+ strcpy(psDBF->pszCodePage, REINTERPRET_CAST(char *, pabyBuf));
}
-/* -------------------------------------------------------------------- */
-/* Read in Field Definitions */
-/* -------------------------------------------------------------------- */
-
- pabyBuf = STATIC_CAST(unsigned char *, SfRealloc(pabyBuf,nHeadLen));
+ /* -------------------------------------------------------------------- */
+ /* Read in Field Definitions */
+ /* -------------------------------------------------------------------- */
+ pabyBuf = STATIC_CAST(unsigned char *, realloc(pabyBuf, nHeadLen));
psDBF->pszHeader = REINTERPRET_CAST(char *, pabyBuf);
- psDBF->sHooks.FSeek( psDBF->fp, XBASE_FILEHDR_SZ, 0 );
- if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-XBASE_FILEHDR_SZ, 1,
- psDBF->fp ) != 1 )
+ psDBF->sHooks.FSeek(psDBF->fp, XBASE_FILEHDR_SZ, 0);
+ if (psDBF->sHooks.FRead(pabyBuf, nHeadLen - XBASE_FILEHDR_SZ, 1,
+ psDBF->fp) != 1)
{
- psDBF->sHooks.FClose( psDBF->fp );
- free( pabyBuf );
- free( psDBF->pszCurrentRecord );
- free( psDBF->pszCodePage );
- free( psDBF );
+ psDBF->sHooks.FClose(psDBF->fp);
+ free(pabyBuf);
+ free(psDBF->pszCurrentRecord);
+ free(psDBF->pszCodePage);
+ free(psDBF);
return SHPLIB_NULLPTR;
}
@@ -675,105 +492,107 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks )
psDBF->panFieldDecimals = STATIC_CAST(int *, malloc(sizeof(int) * nFields));
psDBF->pachFieldType = STATIC_CAST(char *, malloc(sizeof(char) * nFields));
- for( iField = 0; iField < nFields; iField++ )
+ for (int iField = 0; iField < nFields; iField++)
{
- unsigned char *pabyFInfo;
-
- pabyFInfo = pabyBuf+iField*XBASE_FLDHDR_SZ;
- if( pabyFInfo[0] == HEADER_RECORD_TERMINATOR )
+ unsigned char *pabyFInfo = pabyBuf + iField * XBASE_FLDHDR_SZ;
+ if (pabyFInfo[0] == HEADER_RECORD_TERMINATOR)
{
psDBF->nFields = iField;
break;
}
- if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
- {
- psDBF->panFieldSize[iField] = pabyFInfo[16];
- psDBF->panFieldDecimals[iField] = pabyFInfo[17];
- }
- else
- {
- psDBF->panFieldSize[iField] = pabyFInfo[16];
- psDBF->panFieldDecimals[iField] = 0;
-
-/*
-** The following seemed to be used sometimes to handle files with long
-** string fields, but in other cases (such as bug 1202) the decimals field
-** just seems to indicate some sort of preferred formatting, not very
-** wide fields. So I have disabled this code. FrankW.
- psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
- psDBF->panFieldDecimals[iField] = 0;
-*/
- }
-
- psDBF->pachFieldType[iField] = STATIC_CAST(char, pabyFInfo[11]);
- if( iField == 0 )
- psDBF->panFieldOffset[iField] = 1;
- else
- psDBF->panFieldOffset[iField] =
- psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
+ if (pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F')
+ {
+ psDBF->panFieldSize[iField] = pabyFInfo[16];
+ psDBF->panFieldDecimals[iField] = pabyFInfo[17];
+ }
+ else
+ {
+ psDBF->panFieldSize[iField] = pabyFInfo[16];
+ psDBF->panFieldDecimals[iField] = 0;
+
+ /*
+ ** The following seemed to be used sometimes to handle files with
+ long
+ ** string fields, but in other cases (such as bug 1202) the decimals
+ field
+ ** just seems to indicate some sort of preferred formatting, not
+ very
+ ** wide fields. So I have disabled this code. FrankW.
+ psDBF->panFieldSize[iField] = pabyFInfo[16] +
+ pabyFInfo[17]*256; psDBF->panFieldDecimals[iField] = 0;
+ */
+ }
+
+ psDBF->pachFieldType[iField] = STATIC_CAST(char, pabyFInfo[11]);
+ if (iField == 0)
+ psDBF->panFieldOffset[iField] = 1;
+ else
+ psDBF->panFieldOffset[iField] = psDBF->panFieldOffset[iField - 1] +
+ psDBF->panFieldSize[iField - 1];
}
/* Check that the total width of fields does not exceed the record width */
- if( psDBF->nFields > 0 &&
- psDBF->panFieldOffset[psDBF->nFields-1] +
- psDBF->panFieldSize[psDBF->nFields-1] > psDBF->nRecordLength )
+ if (psDBF->nFields > 0 && psDBF->panFieldOffset[psDBF->nFields - 1] +
+ psDBF->panFieldSize[psDBF->nFields - 1] >
+ psDBF->nRecordLength)
{
- DBFClose( psDBF );
+ DBFClose(psDBF);
return SHPLIB_NULLPTR;
}
- DBFSetWriteEndOfFileChar( psDBF, TRUE );
+ DBFSetWriteEndOfFileChar(psDBF, TRUE);
+
+ psDBF->bRequireNextWriteSeek = TRUE;
- return( psDBF );
+ return (psDBF);
}
/************************************************************************/
/* DBFClose() */
/************************************************************************/
-void SHPAPI_CALL
-DBFClose(DBFHandle psDBF)
+void SHPAPI_CALL DBFClose(DBFHandle psDBF)
{
- if( psDBF == SHPLIB_NULLPTR )
+ if (psDBF == SHPLIB_NULLPTR)
return;
-/* -------------------------------------------------------------------- */
-/* Write out header if not already written. */
-/* -------------------------------------------------------------------- */
- if( psDBF->bNoHeader )
- DBFWriteHeader( psDBF );
+ /* -------------------------------------------------------------------- */
+ /* Write out header if not already written. */
+ /* -------------------------------------------------------------------- */
+ if (psDBF->bNoHeader)
+ DBFWriteHeader(psDBF);
- CPL_IGNORE_RET_VAL_INT(DBFFlushRecord( psDBF ));
+ CPL_IGNORE_RET_VAL_INT(DBFFlushRecord(psDBF));
-/* -------------------------------------------------------------------- */
-/* Update last access date, and number of records if we have */
-/* write access. */
-/* -------------------------------------------------------------------- */
- if( psDBF->bUpdated )
- DBFUpdateHeader( psDBF );
+ /* -------------------------------------------------------------------- */
+ /* Update last access date, and number of records if we have */
+ /* write access. */
+ /* -------------------------------------------------------------------- */
+ if (psDBF->bUpdated)
+ DBFUpdateHeader(psDBF);
-/* -------------------------------------------------------------------- */
-/* Close, and free resources. */
-/* -------------------------------------------------------------------- */
- psDBF->sHooks.FClose( psDBF->fp );
+ /* -------------------------------------------------------------------- */
+ /* Close, and free resources. */
+ /* -------------------------------------------------------------------- */
+ psDBF->sHooks.FClose(psDBF->fp);
- if( psDBF->panFieldOffset != SHPLIB_NULLPTR )
+ if (psDBF->panFieldOffset != SHPLIB_NULLPTR)
{
- free( psDBF->panFieldOffset );
- free( psDBF->panFieldSize );
- free( psDBF->panFieldDecimals );
- free( psDBF->pachFieldType );
+ free(psDBF->panFieldOffset);
+ free(psDBF->panFieldSize);
+ free(psDBF->panFieldDecimals);
+ free(psDBF->pachFieldType);
}
- if( psDBF->pszWorkField != SHPLIB_NULLPTR )
- free( psDBF->pszWorkField );
+ if (psDBF->pszWorkField != SHPLIB_NULLPTR)
+ free(psDBF->pszWorkField);
- free( psDBF->pszHeader );
- free( psDBF->pszCurrentRecord );
- free( psDBF->pszCodePage );
+ free(psDBF->pszHeader);
+ free(psDBF->pszCurrentRecord);
+ free(psDBF->pszCodePage);
- free( psDBF );
+ free(psDBF);
}
/************************************************************************/
@@ -782,11 +601,9 @@ DBFClose(DBFHandle psDBF)
/* Create a new .dbf file with default code page LDID/87 (0x57) */
/************************************************************************/
-DBFHandle SHPAPI_CALL
-DBFCreate( const char * pszFilename )
-
+DBFHandle SHPAPI_CALL DBFCreate(const char *pszFilename)
{
- return DBFCreateEx( pszFilename, "LDID/87" ); // 0x57
+ return DBFCreateEx(pszFilename, "LDID/87"); // 0x57
}
/************************************************************************/
@@ -795,15 +612,14 @@ DBFCreate( const char * pszFilename )
/* Create a new .dbf file. */
/************************************************************************/
-DBFHandle SHPAPI_CALL
-DBFCreateEx( const char * pszFilename, const char* pszCodePage )
-
+DBFHandle SHPAPI_CALL DBFCreateEx(const char *pszFilename,
+ const char *pszCodePage)
{
SAHooks sHooks;
- SASetupDefaultHooks( &sHooks );
+ SASetupDefaultHooks(&sHooks);
- return DBFCreateLL( pszFilename, pszCodePage , &sHooks );
+ return DBFCreateLL(pszFilename, pszCodePage, &sHooks);
}
/************************************************************************/
@@ -812,80 +628,69 @@ DBFCreateEx( const char * pszFilename, const char* pszCodePage )
/* Create a new .dbf file. */
/************************************************************************/
-DBFHandle SHPAPI_CALL
-DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHooks )
-
+DBFHandle SHPAPI_CALL DBFCreateLL(const char *pszFilename,
+ const char *pszCodePage,
+ const SAHooks *psHooks)
{
- DBFHandle psDBF;
- SAFile fp;
- char *pszFullname;
- int ldid = -1;
- char chZero = '\0';
- int nLenWithoutExtension;
-
-/* -------------------------------------------------------------------- */
-/* Compute the base (layer) name. If there is any extension */
-/* on the passed in filename we will strip it off. */
-/* -------------------------------------------------------------------- */
- nLenWithoutExtension = DBFGetLenWithoutExtension(pszFilename);
- pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5));
+ /* -------------------------------------------------------------------- */
+ /* Compute the base (layer) name. If there is any extension */
+ /* on the passed in filename we will strip it off. */
+ /* -------------------------------------------------------------------- */
+ const int nLenWithoutExtension = DBFGetLenWithoutExtension(pszFilename);
+ char *pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5));
memcpy(pszFullname, pszFilename, nLenWithoutExtension);
memcpy(pszFullname + nLenWithoutExtension, ".dbf", 5);
-/* -------------------------------------------------------------------- */
-/* Create the file. */
-/* -------------------------------------------------------------------- */
- fp = psHooks->FOpen( pszFullname, "wb" );
- if( fp == SHPLIB_NULLPTR )
- {
- free( pszFullname );
- return SHPLIB_NULLPTR;
- }
-
- psHooks->FWrite( &chZero, 1, 1, fp );
- psHooks->FClose( fp );
-
- fp = psHooks->FOpen( pszFullname, "rb+" );
- if( fp == SHPLIB_NULLPTR )
+ /* -------------------------------------------------------------------- */
+ /* Create the file. */
+ /* -------------------------------------------------------------------- */
+ SAFile fp = psHooks->FOpen(pszFullname, "wb+", psHooks->pvUserData);
+ if (fp == SHPLIB_NULLPTR)
{
- free( pszFullname );
+ free(pszFullname);
return SHPLIB_NULLPTR;
}
memcpy(pszFullname + nLenWithoutExtension, ".cpg", 5);
- if( pszCodePage != SHPLIB_NULLPTR )
+ int ldid = -1;
+ if (pszCodePage != SHPLIB_NULLPTR)
{
- if( strncmp( pszCodePage, "LDID/", 5 ) == 0 )
+ if (strncmp(pszCodePage, "LDID/", 5) == 0)
{
- ldid = atoi( pszCodePage + 5 );
- if( ldid > 255 )
- ldid = -1; // don't use 0 to indicate out of range as LDID/0 is a valid one
+ ldid = atoi(pszCodePage + 5);
+ if (ldid > 255)
+ ldid = -1; // don't use 0 to indicate out of range as LDID/0 is
+ // a valid one
}
- if( ldid < 0 )
+ if (ldid < 0)
{
- SAFile fpCPG = psHooks->FOpen( pszFullname, "w" );
- psHooks->FWrite( CONST_CAST(void*, STATIC_CAST(const void*, pszCodePage)), strlen(pszCodePage), 1, fpCPG );
- psHooks->FClose( fpCPG );
+ SAFile fpCPG =
+ psHooks->FOpen(pszFullname, "w", psHooks->pvUserData);
+ psHooks->FWrite(
+ CONST_CAST(void *, STATIC_CAST(const void *, pszCodePage)),
+ strlen(pszCodePage), 1, fpCPG);
+ psHooks->FClose(fpCPG);
}
}
- if( pszCodePage == SHPLIB_NULLPTR || ldid >= 0 )
+ if (pszCodePage == SHPLIB_NULLPTR || ldid >= 0)
{
- psHooks->Remove( pszFullname );
+ psHooks->Remove(pszFullname, psHooks->pvUserData);
}
- free( pszFullname );
+ free(pszFullname);
-/* -------------------------------------------------------------------- */
-/* Create the info structure. */
-/* -------------------------------------------------------------------- */
- psDBF = STATIC_CAST(DBFHandle, calloc(1,sizeof(DBFInfo)));
+ /* -------------------------------------------------------------------- */
+ /* Create the info structure. */
+ /* -------------------------------------------------------------------- */
+ DBFHandle psDBF = STATIC_CAST(DBFHandle, calloc(1, sizeof(DBFInfo)));
- memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
+ memcpy(&(psDBF->sHooks), psHooks, sizeof(SAHooks));
psDBF->fp = fp;
psDBF->nRecords = 0;
psDBF->nFields = 0;
psDBF->nRecordLength = 1;
- psDBF->nHeaderLength = XBASE_FILEHDR_SZ + 1; /* + 1 for HEADER_RECORD_TERMINATOR */
+ psDBF->nHeaderLength =
+ XBASE_FILEHDR_SZ + 1; /* + 1 for HEADER_RECORD_TERMINATOR */
psDBF->panFieldOffset = SHPLIB_NULLPTR;
psDBF->panFieldSize = SHPLIB_NULLPTR;
@@ -901,16 +706,19 @@ DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHook
psDBF->iLanguageDriver = ldid > 0 ? ldid : 0;
psDBF->pszCodePage = SHPLIB_NULLPTR;
- if( pszCodePage )
+ if (pszCodePage)
{
- psDBF->pszCodePage = STATIC_CAST(char *, malloc( strlen(pszCodePage) + 1 ));
- strcpy( psDBF->pszCodePage, pszCodePage );
+ psDBF->pszCodePage =
+ STATIC_CAST(char *, malloc(strlen(pszCodePage) + 1));
+ strcpy(psDBF->pszCodePage, pszCodePage);
}
DBFSetLastModifiedDate(psDBF, 95, 7, 26); /* dummy date */
DBFSetWriteEndOfFileChar(psDBF, TRUE);
- return( psDBF );
+ psDBF->bRequireNextWriteSeek = TRUE;
+
+ return (psDBF);
}
/************************************************************************/
@@ -919,24 +727,22 @@ DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHook
/* Add a field to a newly created .dbf or to an existing one */
/************************************************************************/
-int SHPAPI_CALL
-DBFAddField(DBFHandle psDBF, const char * pszFieldName,
- DBFFieldType eType, int nWidth, int nDecimals )
-
+int SHPAPI_CALL DBFAddField(DBFHandle psDBF, const char *pszFieldName,
+ DBFFieldType eType, int nWidth, int nDecimals)
{
- char chNativeType = 'C';
+ char chNativeType;
- if( eType == FTLogical )
+ if (eType == FTLogical)
chNativeType = 'L';
- else if( eType == FTDate )
- chNativeType = 'D';
- else if( eType == FTString )
+ else if (eType == FTDate)
+ chNativeType = 'D';
+ else if (eType == FTString)
chNativeType = 'C';
else
chNativeType = 'N';
- return DBFAddNativeFieldType( psDBF, pszFieldName, chNativeType,
- nWidth, nDecimals );
+ return DBFAddNativeFieldType(psDBF, pszFieldName, chNativeType, nWidth,
+ nDecimals);
}
/************************************************************************/
@@ -947,15 +753,15 @@ static char DBFGetNullCharacter(char chType)
{
switch (chType)
{
- case 'N':
- case 'F':
- return '*';
- case 'D':
- return '0';
- case 'L':
- return '?';
- default:
- return ' ';
+ case 'N':
+ case 'F':
+ return '*';
+ case 'D':
+ return '0';
+ case 'L':
+ return '?';
+ default:
+ return ' ';
}
}
@@ -966,102 +772,93 @@ static char DBFGetNullCharacter(char chType)
/* are written. */
/************************************************************************/
-int SHPAPI_CALL
-DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName,
- char chType, int nWidth, int nDecimals )
-
+int SHPAPI_CALL DBFAddNativeFieldType(DBFHandle psDBF, const char *pszFieldName,
+ char chType, int nWidth, int nDecimals)
{
- char *pszFInfo;
- int i;
- int nOldRecordLength, nOldHeaderLength;
- char *pszRecord;
- char chFieldFill;
- SAOffset nRecordOffset;
-
/* make sure that everything is written in .dbf */
- if( !DBFFlushRecord( psDBF ) )
+ if (!DBFFlushRecord(psDBF))
return -1;
- if( psDBF->nHeaderLength + XBASE_FLDHDR_SZ > 65535 )
+ if (psDBF->nHeaderLength + XBASE_FLDHDR_SZ > 65535)
{
char szMessage[128];
- snprintf( szMessage, sizeof(szMessage),
- "Cannot add field %s. Header length limit reached "
- "(max 65535 bytes, 2046 fields).",
- pszFieldName );
- psDBF->sHooks.Error( szMessage );
+ snprintf(szMessage, sizeof(szMessage),
+ "Cannot add field %s. Header length limit reached "
+ "(max 65535 bytes, 2046 fields).",
+ pszFieldName);
+ psDBF->sHooks.Error(szMessage);
return -1;
}
-/* -------------------------------------------------------------------- */
-/* Do some checking to ensure we can add records to this file. */
-/* -------------------------------------------------------------------- */
- if( nWidth < 1 )
+ /* -------------------------------------------------------------------- */
+ /* Do some checking to ensure we can add records to this file. */
+ /* -------------------------------------------------------------------- */
+ if (nWidth < 1)
return -1;
- if( nWidth > XBASE_FLD_MAX_WIDTH )
+ if (nWidth > XBASE_FLD_MAX_WIDTH)
nWidth = XBASE_FLD_MAX_WIDTH;
- if( psDBF->nRecordLength + nWidth > 65535 )
+ if (psDBF->nRecordLength + nWidth > 65535)
{
char szMessage[128];
- snprintf( szMessage, sizeof(szMessage),
- "Cannot add field %s. Record length limit reached "
- "(max 65535 bytes).",
- pszFieldName );
- psDBF->sHooks.Error( szMessage );
+ snprintf(szMessage, sizeof(szMessage),
+ "Cannot add field %s. Record length limit reached "
+ "(max 65535 bytes).",
+ pszFieldName);
+ psDBF->sHooks.Error(szMessage);
return -1;
}
- nOldRecordLength = psDBF->nRecordLength;
- nOldHeaderLength = psDBF->nHeaderLength;
+ const int nOldRecordLength = psDBF->nRecordLength;
+ const int nOldHeaderLength = psDBF->nHeaderLength;
-/* -------------------------------------------------------------------- */
-/* SfRealloc all the arrays larger to hold the additional field */
-/* information. */
-/* -------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+ /* realloc all the arrays larger to hold the additional field */
+ /* information. */
+ /* -------------------------------------------------------------------- */
psDBF->nFields++;
- psDBF->panFieldOffset = STATIC_CAST(int *,
- SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ));
+ psDBF->panFieldOffset = STATIC_CAST(
+ int *, realloc(psDBF->panFieldOffset, sizeof(int) * psDBF->nFields));
- psDBF->panFieldSize = STATIC_CAST(int *,
- SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ));
+ psDBF->panFieldSize = STATIC_CAST(
+ int *, realloc(psDBF->panFieldSize, sizeof(int) * psDBF->nFields));
- psDBF->panFieldDecimals = STATIC_CAST(int *,
- SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ));
+ psDBF->panFieldDecimals = STATIC_CAST(
+ int *, realloc(psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields));
- psDBF->pachFieldType = STATIC_CAST(char *,
- SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields ));
+ psDBF->pachFieldType = STATIC_CAST(
+ char *, realloc(psDBF->pachFieldType, sizeof(char) * psDBF->nFields));
-/* -------------------------------------------------------------------- */
-/* Assign the new field information fields. */
-/* -------------------------------------------------------------------- */
- psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
+ /* -------------------------------------------------------------------- */
+ /* Assign the new field information fields. */
+ /* -------------------------------------------------------------------- */
+ psDBF->panFieldOffset[psDBF->nFields - 1] = psDBF->nRecordLength;
psDBF->nRecordLength += nWidth;
- psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
- psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
- psDBF->pachFieldType[psDBF->nFields-1] = chType;
+ psDBF->panFieldSize[psDBF->nFields - 1] = nWidth;
+ psDBF->panFieldDecimals[psDBF->nFields - 1] = nDecimals;
+ psDBF->pachFieldType[psDBF->nFields - 1] = chType;
-/* -------------------------------------------------------------------- */
-/* Extend the required header information. */
-/* -------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+ /* Extend the required header information. */
+ /* -------------------------------------------------------------------- */
psDBF->nHeaderLength += XBASE_FLDHDR_SZ;
psDBF->bUpdated = FALSE;
- psDBF->pszHeader = STATIC_CAST(char *, SfRealloc(psDBF->pszHeader,
- psDBF->nFields*XBASE_FLDHDR_SZ));
+ psDBF->pszHeader = STATIC_CAST(
+ char *, realloc(psDBF->pszHeader, psDBF->nFields * XBASE_FLDHDR_SZ));
- pszFInfo = psDBF->pszHeader + XBASE_FLDHDR_SZ * (psDBF->nFields-1);
+ char *pszFInfo = psDBF->pszHeader + XBASE_FLDHDR_SZ * (psDBF->nFields - 1);
- for( i = 0; i < XBASE_FLDHDR_SZ; i++ )
+ for (int i = 0; i < XBASE_FLDHDR_SZ; i++)
pszFInfo[i] = '\0';
- strncpy( pszFInfo, pszFieldName, XBASE_FLDNAME_LEN_WRITE );
+ strncpy(pszFInfo, pszFieldName, XBASE_FLDNAME_LEN_WRITE);
- pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
+ pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields - 1];
- if( chType == 'C' )
+ if (chType == 'C')
{
pszFInfo[16] = STATIC_CAST(unsigned char, nWidth % 256);
pszFInfo[17] = STATIC_CAST(unsigned char, nWidth / 256);
@@ -1072,52 +869,61 @@ DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName,
pszFInfo[17] = STATIC_CAST(unsigned char, nDecimals);
}
-/* -------------------------------------------------------------------- */
-/* Make the current record buffer appropriately larger. */
-/* -------------------------------------------------------------------- */
- psDBF->pszCurrentRecord = STATIC_CAST(char *, SfRealloc(psDBF->pszCurrentRecord,
- psDBF->nRecordLength));
+ /* -------------------------------------------------------------------- */
+ /* Make the current record buffer appropriately larger. */
+ /* -------------------------------------------------------------------- */
+ psDBF->pszCurrentRecord = STATIC_CAST(
+ char *, realloc(psDBF->pszCurrentRecord, psDBF->nRecordLength));
/* we're done if dealing with new .dbf */
- if( psDBF->bNoHeader )
- return( psDBF->nFields - 1 );
+ if (psDBF->bNoHeader)
+ return (psDBF->nFields - 1);
-/* -------------------------------------------------------------------- */
-/* For existing .dbf file, shift records */
-/* -------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+ /* For existing .dbf file, shift records */
+ /* -------------------------------------------------------------------- */
/* alloc record */
- pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
+ char *pszRecord =
+ STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
- chFieldFill = DBFGetNullCharacter(chType);
+ const char chFieldFill = DBFGetNullCharacter(chType);
- for (i = psDBF->nRecords-1; i >= 0; --i)
+ SAOffset nRecordOffset;
+ for (int i = psDBF->nRecords - 1; i >= 0; --i)
{
- nRecordOffset = nOldRecordLength * STATIC_CAST(SAOffset, i) + nOldHeaderLength;
+ nRecordOffset =
+ nOldRecordLength * STATIC_CAST(SAOffset, i) + nOldHeaderLength;
/* load record */
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ if (psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1, psDBF->fp) != 1)
+ {
+ free(pszRecord);
+ return -1;
+ }
/* set new field's value to NULL */
memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
- nRecordOffset = psDBF->nRecordLength * STATIC_CAST(SAOffset, i) + psDBF->nHeaderLength;
+ nRecordOffset = psDBF->nRecordLength * STATIC_CAST(SAOffset, i) +
+ psDBF->nHeaderLength;
/* move record to the new place*/
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ psDBF->sHooks.FWrite(pszRecord, psDBF->nRecordLength, 1, psDBF->fp);
}
- if( psDBF->bWriteEndOfFileChar )
+ if (psDBF->bWriteEndOfFileChar)
{
char ch = END_OF_FILE_CHARACTER;
nRecordOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength;
+ psDBF->nRecordLength * STATIC_CAST(SAOffset, psDBF->nRecords) +
+ psDBF->nHeaderLength;
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ psDBF->sHooks.FWrite(&ch, 1, 1, psDBF->fp);
}
/* free record */
@@ -1125,13 +931,13 @@ DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName,
/* force update of header with new header, record length and new field */
psDBF->bNoHeader = TRUE;
- DBFUpdateHeader( psDBF );
+ DBFUpdateHeader(psDBF);
psDBF->nCurrentRecord = -1;
psDBF->bCurrentRecordModified = FALSE;
psDBF->bUpdated = TRUE;
- return( psDBF->nFields-1 );
+ return (psDBF->nFields - 1);
}
/************************************************************************/
@@ -1141,64 +947,64 @@ DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName,
/************************************************************************/
static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
- char chReqType )
-
+ char chReqType)
{
- unsigned char *pabyRec;
- void *pReturnField = SHPLIB_NULLPTR;
-
-/* -------------------------------------------------------------------- */
-/* Verify selection. */
-/* -------------------------------------------------------------------- */
- if( hEntity < 0 || hEntity >= psDBF->nRecords )
+ /* -------------------------------------------------------------------- */
+ /* Verify selection. */
+ /* -------------------------------------------------------------------- */
+ if (hEntity < 0 || hEntity >= psDBF->nRecords)
return SHPLIB_NULLPTR;
- if( iField < 0 || iField >= psDBF->nFields )
+ if (iField < 0 || iField >= psDBF->nFields)
return SHPLIB_NULLPTR;
-/* -------------------------------------------------------------------- */
-/* Have we read the record? */
-/* -------------------------------------------------------------------- */
- if( !DBFLoadRecord( psDBF, hEntity ) )
+ /* -------------------------------------------------------------------- */
+ /* Have we read the record? */
+ /* -------------------------------------------------------------------- */
+ if (!DBFLoadRecord(psDBF, hEntity))
return SHPLIB_NULLPTR;
- pabyRec = REINTERPRET_CAST(unsigned char *, psDBF->pszCurrentRecord);
+ const unsigned char *pabyRec =
+ REINTERPRET_CAST(const unsigned char *, psDBF->pszCurrentRecord);
-/* -------------------------------------------------------------------- */
-/* Ensure we have room to extract the target field. */
-/* -------------------------------------------------------------------- */
- if( psDBF->panFieldSize[iField] >= psDBF->nWorkFieldLength )
+ /* -------------------------------------------------------------------- */
+ /* Ensure we have room to extract the target field. */
+ /* -------------------------------------------------------------------- */
+ if (psDBF->panFieldSize[iField] >= psDBF->nWorkFieldLength)
{
psDBF->nWorkFieldLength = psDBF->panFieldSize[iField] + 100;
- if( psDBF->pszWorkField == SHPLIB_NULLPTR )
- psDBF->pszWorkField = STATIC_CAST(char *, malloc(psDBF->nWorkFieldLength));
+ if (psDBF->pszWorkField == SHPLIB_NULLPTR)
+ psDBF->pszWorkField =
+ STATIC_CAST(char *, malloc(psDBF->nWorkFieldLength));
else
- psDBF->pszWorkField = STATIC_CAST(char *, realloc(psDBF->pszWorkField,
- psDBF->nWorkFieldLength));
+ psDBF->pszWorkField = STATIC_CAST(
+ char *, realloc(psDBF->pszWorkField, psDBF->nWorkFieldLength));
}
-/* -------------------------------------------------------------------- */
-/* Extract the requested field. */
-/* -------------------------------------------------------------------- */
- memcpy( psDBF->pszWorkField,
- REINTERPRET_CAST(const char *, pabyRec) + psDBF->panFieldOffset[iField],
- psDBF->panFieldSize[iField] );
+ /* -------------------------------------------------------------------- */
+ /* Extract the requested field. */
+ /* -------------------------------------------------------------------- */
+ memcpy(psDBF->pszWorkField,
+ REINTERPRET_CAST(const char *, pabyRec) +
+ psDBF->panFieldOffset[iField],
+ psDBF->panFieldSize[iField]);
psDBF->pszWorkField[psDBF->panFieldSize[iField]] = '\0';
- pReturnField = psDBF->pszWorkField;
+ void *pReturnField = psDBF->pszWorkField;
-/* -------------------------------------------------------------------- */
-/* Decode the field. */
-/* -------------------------------------------------------------------- */
- if( chReqType == 'I' )
+ /* -------------------------------------------------------------------- */
+ /* Decode the field. */
+ /* -------------------------------------------------------------------- */
+ if (chReqType == 'I')
{
psDBF->fieldValue.nIntField = atoi(psDBF->pszWorkField);
pReturnField = &(psDBF->fieldValue.nIntField);
}
- else if( chReqType == 'N' )
+ else if (chReqType == 'N')
{
- psDBF->fieldValue.dfDoubleField = psDBF->sHooks.Atof(psDBF->pszWorkField);
+ psDBF->fieldValue.dfDoubleField =
+ psDBF->sHooks.Atof(psDBF->pszWorkField);
pReturnField = &(psDBF->fieldValue.dfDoubleField);
}
@@ -1209,17 +1015,17 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
#ifdef TRIM_DBF_WHITESPACE
else
{
- char *pchSrc, *pchDst;
+ char *pchSrc = psDBF->pszWorkField;
+ char *pchDst = pchSrc;
- pchDst = pchSrc = psDBF->pszWorkField;
- while( *pchSrc == ' ' )
+ while (*pchSrc == ' ')
pchSrc++;
- while( *pchSrc != '\0' )
+ while (*pchSrc != '\0')
*(pchDst++) = *(pchSrc++);
*pchDst = '\0';
- while( pchDst != psDBF->pszWorkField && *(--pchDst) == ' ' )
+ while (pchDst != psDBF->pszWorkField && *(--pchDst) == ' ')
*pchDst = '\0';
}
#endif
@@ -1233,15 +1039,13 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
/* Read an integer attribute. */
/************************************************************************/
-int SHPAPI_CALL
-DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField )
-
+int SHPAPI_CALL DBFReadIntegerAttribute(DBFHandle psDBF, int iRecord,
+ int iField)
{
- int *pnValue;
-
- pnValue = STATIC_CAST(int *, DBFReadAttribute( psDBF, iRecord, iField, 'I' ));
+ int *pnValue =
+ STATIC_CAST(int *, DBFReadAttribute(psDBF, iRecord, iField, 'I'));
- if( pnValue == SHPLIB_NULLPTR )
+ if (pnValue == SHPLIB_NULLPTR)
return 0;
else
return *pnValue;
@@ -1253,18 +1057,16 @@ DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField )
/* Read a double attribute. */
/************************************************************************/
-double SHPAPI_CALL
-DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField )
-
+double SHPAPI_CALL DBFReadDoubleAttribute(DBFHandle psDBF, int iRecord,
+ int iField)
{
- double *pdValue;
-
- pdValue = STATIC_CAST(double *, DBFReadAttribute( psDBF, iRecord, iField, 'N' ));
+ double *pdValue =
+ STATIC_CAST(double *, DBFReadAttribute(psDBF, iRecord, iField, 'N'));
- if( pdValue == SHPLIB_NULLPTR )
+ if (pdValue == SHPLIB_NULLPTR)
return 0.0;
else
- return *pdValue ;
+ return *pdValue;
}
/************************************************************************/
@@ -1274,10 +1076,11 @@ DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField )
/************************************************************************/
const char SHPAPI_CALL1(*)
-DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField )
+ DBFReadStringAttribute(DBFHandle psDBF, int iRecord, int iField)
{
- return STATIC_CAST(const char *, DBFReadAttribute( psDBF, iRecord, iField, 'C' ) );
+ return STATIC_CAST(const char *,
+ DBFReadAttribute(psDBF, iRecord, iField, 'C'));
}
/************************************************************************/
@@ -1287,56 +1090,59 @@ DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField )
/************************************************************************/
const char SHPAPI_CALL1(*)
-DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField )
+ DBFReadLogicalAttribute(DBFHandle psDBF, int iRecord, int iField)
{
- return STATIC_CAST(const char *, DBFReadAttribute( psDBF, iRecord, iField, 'L' ) );
+ return STATIC_CAST(const char *,
+ DBFReadAttribute(psDBF, iRecord, iField, 'L'));
}
-
/************************************************************************/
/* DBFIsValueNULL() */
/* */
/* Return TRUE if the passed string is NULL. */
/************************************************************************/
-static int DBFIsValueNULL( char chType, const char* pszValue )
+static bool DBFIsValueNULL(char chType, const char *pszValue)
{
- int i;
-
- if( pszValue == SHPLIB_NULLPTR )
- return TRUE;
+ if (pszValue == SHPLIB_NULLPTR)
+ return true;
- switch(chType)
+ switch (chType)
{
- case 'N':
- case 'F':
- /*
- ** We accept all asterisks or all blanks as NULL
- ** though according to the spec I think it should be all
- ** asterisks.
- */
- if( pszValue[0] == '*' )
- return TRUE;
-
- for( i = 0; pszValue[i] != '\0'; i++ )
- {
- if( pszValue[i] != ' ' )
- return FALSE;
- }
- return TRUE;
-
- case 'D':
- /* NULL date fields have value "00000000" */
- return strncmp(pszValue,"00000000",8) == 0;
-
- case 'L':
- /* NULL boolean fields have value "?" */
- return pszValue[0] == '?';
-
- default:
- /* empty string fields are considered NULL */
- return strlen(pszValue) == 0;
+ case 'N':
+ case 'F':
+ /*
+ ** We accept all asterisks or all blanks as NULL
+ ** though according to the spec I think it should be all
+ ** asterisks.
+ */
+ if (pszValue[0] == '*')
+ return true;
+
+ for (int i = 0; pszValue[i] != '\0'; i++)
+ {
+ if (pszValue[i] != ' ')
+ return false;
+ }
+ return true;
+
+ case 'D':
+ /* NULL date fields have value "00000000" */
+ /* Some DBF files have fields filled with spaces */
+ /* (trimmed by DBFReadStringAttribute) to indicate null */
+ /* values for dates (#4265). */
+ /* And others have ' 0': https://lists.osgeo.org/pipermail/gdal-dev/2023-November/058010.html */
+ return strncmp(pszValue, "00000000", 8) == 0 ||
+ strcmp(pszValue, " ") == 0 || strcmp(pszValue, "0") == 0;
+
+ case 'L':
+ /* NULL boolean fields have value "?" */
+ return pszValue[0] == '?';
+
+ default:
+ /* empty string fields are considered NULL */
+ return strlen(pszValue) == 0;
}
}
@@ -1348,18 +1154,14 @@ static int DBFIsValueNULL( char chType, const char* pszValue )
/* Contributed by Jim Matthews. */
/************************************************************************/
-int SHPAPI_CALL
-DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
-
+int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle psDBF, int iRecord, int iField)
{
- const char *pszValue;
-
- pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
+ const char *pszValue = DBFReadStringAttribute(psDBF, iRecord, iField);
- if( pszValue == SHPLIB_NULLPTR )
+ if (pszValue == SHPLIB_NULLPTR)
return TRUE;
- return DBFIsValueNULL( psDBF->pachFieldType[iField], pszValue );
+ return DBFIsValueNULL(psDBF->pachFieldType[iField], pszValue);
}
/************************************************************************/
@@ -1368,11 +1170,10 @@ DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
/* Return the number of fields in this table. */
/************************************************************************/
-int SHPAPI_CALL
-DBFGetFieldCount( DBFHandle psDBF )
+int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF)
{
- return( psDBF->nFields );
+ return (psDBF->nFields);
}
/************************************************************************/
@@ -1381,11 +1182,10 @@ DBFGetFieldCount( DBFHandle psDBF )
/* Return the number of records in this table. */
/************************************************************************/
-int SHPAPI_CALL
-DBFGetRecordCount( DBFHandle psDBF )
+int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF)
{
- return( psDBF->nRecords );
+ return (psDBF->nRecords);
}
/************************************************************************/
@@ -1396,168 +1196,179 @@ DBFGetRecordCount( DBFHandle psDBF )
/* bytes long. */
/************************************************************************/
-DBFFieldType SHPAPI_CALL
-DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName,
- int * pnWidth, int * pnDecimals )
+DBFFieldType SHPAPI_CALL DBFGetFieldInfo(DBFHandle psDBF, int iField,
+ char *pszFieldName, int *pnWidth,
+ int *pnDecimals)
{
- if( iField < 0 || iField >= psDBF->nFields )
- return( FTInvalid );
+ if (iField < 0 || iField >= psDBF->nFields)
+ return (FTInvalid);
- if( pnWidth != SHPLIB_NULLPTR )
+ if (pnWidth != SHPLIB_NULLPTR)
*pnWidth = psDBF->panFieldSize[iField];
- if( pnDecimals != SHPLIB_NULLPTR )
+ if (pnDecimals != SHPLIB_NULLPTR)
*pnDecimals = psDBF->panFieldDecimals[iField];
- if( pszFieldName != SHPLIB_NULLPTR )
+ if (pszFieldName != SHPLIB_NULLPTR)
{
- int i;
-
- strncpy( pszFieldName, STATIC_CAST(char *,psDBF->pszHeader)+iField*XBASE_FLDHDR_SZ,
- XBASE_FLDNAME_LEN_READ );
- pszFieldName[XBASE_FLDNAME_LEN_READ] = '\0';
- for( i = XBASE_FLDNAME_LEN_READ - 1; i > 0 && pszFieldName[i] == ' '; i-- )
- pszFieldName[i] = '\0';
+ strncpy(pszFieldName,
+ STATIC_CAST(char *, psDBF->pszHeader) +
+ iField * XBASE_FLDHDR_SZ,
+ XBASE_FLDNAME_LEN_READ);
+ pszFieldName[XBASE_FLDNAME_LEN_READ] = '\0';
+ for (int i = XBASE_FLDNAME_LEN_READ - 1;
+ i > 0 && pszFieldName[i] == ' '; i--)
+ pszFieldName[i] = '\0';
}
- if ( psDBF->pachFieldType[iField] == 'L' )
- return( FTLogical );
+ if (psDBF->pachFieldType[iField] == 'L')
+ return (FTLogical);
- else if( psDBF->pachFieldType[iField] == 'D' )
- return( FTDate );
+ else if (psDBF->pachFieldType[iField] == 'D')
+ return (FTDate);
- else if( psDBF->pachFieldType[iField] == 'N'
- || psDBF->pachFieldType[iField] == 'F' )
+ else if (psDBF->pachFieldType[iField] == 'N' ||
+ psDBF->pachFieldType[iField] == 'F')
{
- if( psDBF->panFieldDecimals[iField] > 0
- || psDBF->panFieldSize[iField] >= 10 )
- return( FTDouble );
- else
- return( FTInteger );
+ if (psDBF->panFieldDecimals[iField] > 0 ||
+ psDBF->panFieldSize[iField] >= 10)
+ return (FTDouble);
+ else
+ return (FTInteger);
}
else
{
- return( FTString );
+ return (FTString);
}
}
/************************************************************************/
/* DBFWriteAttribute() */
-/* */
-/* Write an attribute record to the file. */
+/* */
+/* Write an attribute record to the file. */
/************************************************************************/
-static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
- void * pValue )
-
+static bool DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
+ void *pValue)
{
- int i, j, nRetResult = TRUE;
- unsigned char *pabyRec;
- char szSField[XBASE_FLD_MAX_WIDTH+1], szFormat[20];
-
-/* -------------------------------------------------------------------- */
-/* Is this a valid record? */
-/* -------------------------------------------------------------------- */
- if( hEntity < 0 || hEntity > psDBF->nRecords )
- return( FALSE );
+ /* -------------------------------------------------------------------- */
+ /* Is this a valid record? */
+ /* -------------------------------------------------------------------- */
+ if (hEntity < 0 || hEntity > psDBF->nRecords)
+ return false;
- if( psDBF->bNoHeader )
+ if (psDBF->bNoHeader)
DBFWriteHeader(psDBF);
-/* -------------------------------------------------------------------- */
-/* Is this a brand new record? */
-/* -------------------------------------------------------------------- */
- if( hEntity == psDBF->nRecords )
+ /* -------------------------------------------------------------------- */
+ /* Is this a brand new record? */
+ /* -------------------------------------------------------------------- */
+ if (hEntity == psDBF->nRecords)
{
- if( !DBFFlushRecord( psDBF ) )
- return FALSE;
+ if (!DBFFlushRecord(psDBF))
+ return false;
- psDBF->nRecords++;
- for( i = 0; i < psDBF->nRecordLength; i++ )
- psDBF->pszCurrentRecord[i] = ' ';
+ psDBF->nRecords++;
+ for (int i = 0; i < psDBF->nRecordLength; i++)
+ psDBF->pszCurrentRecord[i] = ' ';
- psDBF->nCurrentRecord = hEntity;
+ psDBF->nCurrentRecord = hEntity;
}
-/* -------------------------------------------------------------------- */
-/* Is this an existing record, but different than the last one */
-/* we accessed? */
-/* -------------------------------------------------------------------- */
- if( !DBFLoadRecord( psDBF, hEntity ) )
- return FALSE;
+ /* -------------------------------------------------------------------- */
+ /* Is this an existing record, but different than the last one */
+ /* we accessed? */
+ /* -------------------------------------------------------------------- */
+ if (!DBFLoadRecord(psDBF, hEntity))
+ return false;
- pabyRec = REINTERPRET_CAST(unsigned char *,psDBF->pszCurrentRecord);
+ unsigned char *pabyRec =
+ REINTERPRET_CAST(unsigned char *, psDBF->pszCurrentRecord);
psDBF->bCurrentRecordModified = TRUE;
psDBF->bUpdated = TRUE;
-/* -------------------------------------------------------------------- */
-/* Translate NULL value to valid DBF file representation. */
-/* */
-/* Contributed by Jim Matthews. */
-/* -------------------------------------------------------------------- */
- if( pValue == SHPLIB_NULLPTR )
+ /* -------------------------------------------------------------------- */
+ /* Translate NULL value to valid DBF file representation. */
+ /* */
+ /* Contributed by Jim Matthews. */
+ /* -------------------------------------------------------------------- */
+ if (pValue == SHPLIB_NULLPTR)
{
- memset( pabyRec+psDBF->panFieldOffset[iField],
- DBFGetNullCharacter(psDBF->pachFieldType[iField]),
- psDBF->panFieldSize[iField] );
- return TRUE;
+ memset(pabyRec + psDBF->panFieldOffset[iField],
+ DBFGetNullCharacter(psDBF->pachFieldType[iField]),
+ psDBF->panFieldSize[iField]);
+ return true;
}
-/* -------------------------------------------------------------------- */
-/* Assign all the record fields. */
-/* -------------------------------------------------------------------- */
- switch( psDBF->pachFieldType[iField] )
+ /* -------------------------------------------------------------------- */
+ /* Assign all the record fields. */
+ /* -------------------------------------------------------------------- */
+ bool nRetResult = true;
+
+ switch (psDBF->pachFieldType[iField])
{
- case 'D':
- case 'N':
- case 'F':
- {
- int nWidth = psDBF->panFieldSize[iField];
-
- if( STATIC_CAST(int,sizeof(szSField))-2 < nWidth )
- nWidth = sizeof(szSField)-2;
-
- snprintf( szFormat, sizeof(szFormat), "%%%d.%df",
- nWidth, psDBF->panFieldDecimals[iField] );
- CPLsnprintf(szSField, sizeof(szSField), szFormat, *STATIC_CAST(double *, pValue) );
- szSField[sizeof(szSField)-1] = '\0';
- if( STATIC_CAST(int,strlen(szSField)) > psDBF->panFieldSize[iField] )
+ case 'D':
+ case 'N':
+ case 'F':
{
- szSField[psDBF->panFieldSize[iField]] = '\0';
- nRetResult = FALSE;
- }
- strncpy(REINTERPRET_CAST(char *, pabyRec+psDBF->panFieldOffset[iField]),
- szSField, strlen(szSField) );
- break;
- }
-
- case 'L':
- if (psDBF->panFieldSize[iField] >= 1 &&
- (*STATIC_CAST(char*,pValue) == 'F' || *STATIC_CAST(char*,pValue) == 'T'))
- *(pabyRec+psDBF->panFieldOffset[iField]) = *STATIC_CAST(char*,pValue);
- break;
-
- default:
- if( STATIC_CAST(int, strlen(STATIC_CAST(char *,pValue))) > psDBF->panFieldSize[iField] )
- {
- j = psDBF->panFieldSize[iField];
- nRetResult = FALSE;
+ int nWidth = psDBF->panFieldSize[iField];
+
+ char szSField[XBASE_FLD_MAX_WIDTH + 1];
+ if (STATIC_CAST(int, sizeof(szSField)) - 2 < nWidth)
+ nWidth = sizeof(szSField) - 2;
+
+ char szFormat[20];
+ snprintf(szFormat, sizeof(szFormat), "%%%d.%df", nWidth,
+ psDBF->panFieldDecimals[iField]);
+ CPLsnprintf(szSField, sizeof(szSField), szFormat,
+ *STATIC_CAST(double *, pValue));
+ szSField[sizeof(szSField) - 1] = '\0';
+ if (STATIC_CAST(int, strlen(szSField)) >
+ psDBF->panFieldSize[iField])
+ {
+ szSField[psDBF->panFieldSize[iField]] = '\0';
+ nRetResult = false;
+ }
+ memcpy(REINTERPRET_CAST(char *,
+ pabyRec + psDBF->panFieldOffset[iField]),
+ szSField, strlen(szSField));
+ break;
}
- else
+
+ case 'L':
+ if (psDBF->panFieldSize[iField] >= 1 &&
+ (*STATIC_CAST(char *, pValue) == 'F' ||
+ *STATIC_CAST(char *, pValue) == 'T'))
+ *(pabyRec + psDBF->panFieldOffset[iField]) =
+ *STATIC_CAST(char *, pValue);
+ break;
+
+ default:
{
- memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
- psDBF->panFieldSize[iField] );
- j = STATIC_CAST(int, strlen(STATIC_CAST(char *,pValue)));
- }
+ int j;
+ if (STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue))) >
+ psDBF->panFieldSize[iField])
+ {
+ j = psDBF->panFieldSize[iField];
+ nRetResult = false;
+ }
+ else
+ {
+ memset(pabyRec + psDBF->panFieldOffset[iField], ' ',
+ psDBF->panFieldSize[iField]);
+ j = STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue)));
+ }
- strncpy(REINTERPRET_CAST(char *, pabyRec+psDBF->panFieldOffset[iField]),
- STATIC_CAST(const char *, pValue), j );
- break;
+ strncpy(REINTERPRET_CAST(char *,
+ pabyRec + psDBF->panFieldOffset[iField]),
+ STATIC_CAST(const char *, pValue), j);
+ break;
+ }
}
- return( nRetResult );
+ return nRetResult;
}
/************************************************************************/
@@ -1568,66 +1379,68 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
/* as is to the field position in the record. */
/************************************************************************/
-int SHPAPI_CALL
-DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
- void * pValue )
-
+int SHPAPI_CALL DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity,
+ int iField, const void *pValue)
{
- int i, j;
- unsigned char *pabyRec;
+ /* -------------------------------------------------------------------- */
+ /* Is this a valid record? */
+ /* -------------------------------------------------------------------- */
+ if (hEntity < 0 || hEntity > psDBF->nRecords)
+ return (FALSE);
-/* -------------------------------------------------------------------- */
-/* Is this a valid record? */
-/* -------------------------------------------------------------------- */
- if( hEntity < 0 || hEntity > psDBF->nRecords )
- return( FALSE );
-
- if( psDBF->bNoHeader )
+ if (psDBF->bNoHeader)
DBFWriteHeader(psDBF);
-/* -------------------------------------------------------------------- */
-/* Is this a brand new record? */
-/* -------------------------------------------------------------------- */
- if( hEntity == psDBF->nRecords )
+ /* -------------------------------------------------------------------- */
+ /* Is this a brand new record? */
+ /* -------------------------------------------------------------------- */
+ if (hEntity == psDBF->nRecords)
{
- if( !DBFFlushRecord( psDBF ) )
+ if (!DBFFlushRecord(psDBF))
return FALSE;
- psDBF->nRecords++;
- for( i = 0; i < psDBF->nRecordLength; i++ )
- psDBF->pszCurrentRecord[i] = ' ';
+ psDBF->nRecords++;
+ for (int i = 0; i < psDBF->nRecordLength; i++)
+ psDBF->pszCurrentRecord[i] = ' ';
- psDBF->nCurrentRecord = hEntity;
+ psDBF->nCurrentRecord = hEntity;
}
-/* -------------------------------------------------------------------- */
-/* Is this an existing record, but different than the last one */
-/* we accessed? */
-/* -------------------------------------------------------------------- */
- if( !DBFLoadRecord( psDBF, hEntity ) )
+ /* -------------------------------------------------------------------- */
+ /* Is this an existing record, but different than the last one */
+ /* we accessed? */
+ /* -------------------------------------------------------------------- */
+ if (!DBFLoadRecord(psDBF, hEntity))
return FALSE;
- pabyRec = REINTERPRET_CAST(unsigned char *, psDBF->pszCurrentRecord);
-
-/* -------------------------------------------------------------------- */
-/* Assign all the record fields. */
-/* -------------------------------------------------------------------- */
- if( STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue))) > psDBF->panFieldSize[iField] )
- j = psDBF->panFieldSize[iField];
- else
+ if (iField >= 0)
{
- memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
- psDBF->panFieldSize[iField] );
- j = STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue)));
- }
+ unsigned char *pabyRec =
+ REINTERPRET_CAST(unsigned char *, psDBF->pszCurrentRecord);
+
+ /* -------------------------------------------------------------------- */
+ /* Assign all the record fields. */
+ /* -------------------------------------------------------------------- */
+ int j;
+ if (STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue))) >
+ psDBF->panFieldSize[iField])
+ j = psDBF->panFieldSize[iField];
+ else
+ {
+ memset(pabyRec + psDBF->panFieldOffset[iField], ' ',
+ psDBF->panFieldSize[iField]);
+ j = STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue)));
+ }
- strncpy(REINTERPRET_CAST(char *, pabyRec+psDBF->panFieldOffset[iField]),
- STATIC_CAST(const char *, pValue), j );
+ strncpy(
+ REINTERPRET_CAST(char *, pabyRec + psDBF->panFieldOffset[iField]),
+ STATIC_CAST(const char *, pValue), j);
+ }
psDBF->bCurrentRecordModified = TRUE;
psDBF->bUpdated = TRUE;
- return( TRUE );
+ return (TRUE);
}
/************************************************************************/
@@ -1636,12 +1449,11 @@ DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
/* Write a double attribute. */
/************************************************************************/
-int SHPAPI_CALL
-DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField,
- double dValue )
-
+int SHPAPI_CALL DBFWriteDoubleAttribute(DBFHandle psDBF, int iRecord,
+ int iField, double dValue)
{
- return( DBFWriteAttribute( psDBF, iRecord, iField, STATIC_CAST(void *, &dValue) ) );
+ return (DBFWriteAttribute(psDBF, iRecord, iField,
+ STATIC_CAST(void *, &dValue)));
}
/************************************************************************/
@@ -1650,14 +1462,13 @@ DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField,
/* Write a integer attribute. */
/************************************************************************/
-int SHPAPI_CALL
-DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField,
- int nValue )
-
+int SHPAPI_CALL DBFWriteIntegerAttribute(DBFHandle psDBF, int iRecord,
+ int iField, int nValue)
{
- double dValue = nValue;
+ double dValue = nValue;
- return( DBFWriteAttribute( psDBF, iRecord, iField, STATIC_CAST(void *, &dValue) ) );
+ return (DBFWriteAttribute(psDBF, iRecord, iField,
+ STATIC_CAST(void *, &dValue)));
}
/************************************************************************/
@@ -1666,12 +1477,13 @@ DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField,
/* Write a string attribute. */
/************************************************************************/
-int SHPAPI_CALL
-DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField,
- const char * pszValue )
+int SHPAPI_CALL DBFWriteStringAttribute(DBFHandle psDBF, int iRecord,
+ int iField, const char *pszValue)
{
- return( DBFWriteAttribute( psDBF, iRecord, iField, STATIC_CAST(void *, CONST_CAST(char*, pszValue))) );
+ return (
+ DBFWriteAttribute(psDBF, iRecord, iField,
+ STATIC_CAST(void *, CONST_CAST(char *, pszValue))));
}
/************************************************************************/
@@ -1680,11 +1492,10 @@ DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField,
/* Write a string attribute. */
/************************************************************************/
-int SHPAPI_CALL
-DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField )
+int SHPAPI_CALL DBFWriteNULLAttribute(DBFHandle psDBF, int iRecord, int iField)
{
- return( DBFWriteAttribute( psDBF, iRecord, iField, SHPLIB_NULLPTR ) );
+ return (DBFWriteAttribute(psDBF, iRecord, iField, SHPLIB_NULLPTR));
}
/************************************************************************/
@@ -1693,66 +1504,64 @@ DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField )
/* Write a logical attribute. */
/************************************************************************/
-int SHPAPI_CALL
-DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField,
- const char lValue)
+int SHPAPI_CALL DBFWriteLogicalAttribute(DBFHandle psDBF, int iRecord,
+ int iField, const char lValue)
{
- return( DBFWriteAttribute( psDBF, iRecord, iField, STATIC_CAST(void *, CONST_CAST(char*, &lValue)) ) );
+ return (
+ DBFWriteAttribute(psDBF, iRecord, iField,
+ STATIC_CAST(void *, CONST_CAST(char *, &lValue))));
}
/************************************************************************/
/* DBFWriteTuple() */
-/* */
-/* Write an attribute record to the file. */
+/* */
+/* Write an attribute record to the file. */
/************************************************************************/
-int SHPAPI_CALL
-DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
-
+int SHPAPI_CALL DBFWriteTuple(DBFHandle psDBF, int hEntity,
+ const void *pRawTuple)
{
- int i;
- unsigned char *pabyRec;
+ /* -------------------------------------------------------------------- */
+ /* Is this a valid record? */
+ /* -------------------------------------------------------------------- */
+ if (hEntity < 0 || hEntity > psDBF->nRecords)
+ return (FALSE);
-/* -------------------------------------------------------------------- */
-/* Is this a valid record? */
-/* -------------------------------------------------------------------- */
- if( hEntity < 0 || hEntity > psDBF->nRecords )
- return( FALSE );
-
- if( psDBF->bNoHeader )
+ if (psDBF->bNoHeader)
DBFWriteHeader(psDBF);
-/* -------------------------------------------------------------------- */
-/* Is this a brand new record? */
-/* -------------------------------------------------------------------- */
- if( hEntity == psDBF->nRecords )
+ /* -------------------------------------------------------------------- */
+ /* Is this a brand new record? */
+ /* -------------------------------------------------------------------- */
+ if (hEntity == psDBF->nRecords)
{
- if( !DBFFlushRecord( psDBF ) )
+ if (!DBFFlushRecord(psDBF))
return FALSE;
- psDBF->nRecords++;
- for( i = 0; i < psDBF->nRecordLength; i++ )
- psDBF->pszCurrentRecord[i] = ' ';
+ psDBF->nRecords++;
+ for (int i = 0; i < psDBF->nRecordLength; i++)
+ psDBF->pszCurrentRecord[i] = ' ';
- psDBF->nCurrentRecord = hEntity;
+ psDBF->nCurrentRecord = hEntity;
}
-/* -------------------------------------------------------------------- */
-/* Is this an existing record, but different than the last one */
-/* we accessed? */
-/* -------------------------------------------------------------------- */
- if( !DBFLoadRecord( psDBF, hEntity ) )
+ /* -------------------------------------------------------------------- */
+ /* Is this an existing record, but different than the last one */
+ /* we accessed? */
+ /* -------------------------------------------------------------------- */
+ if (!DBFLoadRecord(psDBF, hEntity))
return FALSE;
- pabyRec = REINTERPRET_CAST(unsigned char *, psDBF->pszCurrentRecord);
+ unsigned char *pabyRec =
+ REINTERPRET_CAST(unsigned char *, psDBF->pszCurrentRecord);
- memcpy ( pabyRec, pRawTuple, psDBF->nRecordLength );
+ memcpy(pabyRec, pRawTuple, psDBF->nRecordLength);
psDBF->bCurrentRecordModified = TRUE;
psDBF->bUpdated = TRUE;
- return( TRUE );
+ return (TRUE);
}
/************************************************************************/
@@ -1762,63 +1571,70 @@ DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
/* till the next record read for any reason. */
/************************************************************************/
-const char SHPAPI_CALL1(*)
-DBFReadTuple(DBFHandle psDBF, int hEntity )
+const char SHPAPI_CALL1(*) DBFReadTuple(DBFHandle psDBF, int hEntity)
{
- if( hEntity < 0 || hEntity >= psDBF->nRecords )
+ if (hEntity < 0 || hEntity >= psDBF->nRecords)
return SHPLIB_NULLPTR;
- if( !DBFLoadRecord( psDBF, hEntity ) )
+ if (!DBFLoadRecord(psDBF, hEntity))
return SHPLIB_NULLPTR;
return STATIC_CAST(const char *, psDBF->pszCurrentRecord);
}
/************************************************************************/
-/* DBFCloneEmpty() */
+/* DBFCloneEmpty() */
/* */
/* Read one of the attribute fields of a record. */
/************************************************************************/
-DBFHandle SHPAPI_CALL
-DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename )
+DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF, const char *pszFilename)
{
- DBFHandle newDBF;
-
- newDBF = DBFCreateEx ( pszFilename, psDBF->pszCodePage );
- if ( newDBF == SHPLIB_NULLPTR ) return SHPLIB_NULLPTR;
-
- newDBF->nFields = psDBF->nFields;
- newDBF->nRecordLength = psDBF->nRecordLength;
- newDBF->nHeaderLength = psDBF->nHeaderLength;
-
- if( psDBF->pszHeader )
- {
- newDBF->pszHeader = STATIC_CAST(char *, malloc ( XBASE_FLDHDR_SZ * psDBF->nFields ));
- memcpy ( newDBF->pszHeader, psDBF->pszHeader, XBASE_FLDHDR_SZ * psDBF->nFields );
- }
-
- newDBF->panFieldOffset = STATIC_CAST(int *, malloc ( sizeof(int) * psDBF->nFields ));
- memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
- newDBF->panFieldSize = STATIC_CAST(int *, malloc ( sizeof(int) * psDBF->nFields ));
- memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
- newDBF->panFieldDecimals = STATIC_CAST(int *, malloc ( sizeof(int) * psDBF->nFields ));
- memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
- newDBF->pachFieldType = STATIC_CAST(char *, malloc ( sizeof(char) * psDBF->nFields ));
- memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(char)*psDBF->nFields );
-
- newDBF->bNoHeader = TRUE;
- newDBF->bUpdated = TRUE;
- newDBF->bWriteEndOfFileChar = psDBF->bWriteEndOfFileChar;
+ DBFHandle newDBF = DBFCreateEx(pszFilename, psDBF->pszCodePage);
+ if (newDBF == SHPLIB_NULLPTR)
+ return SHPLIB_NULLPTR;
- DBFWriteHeader ( newDBF );
- DBFClose ( newDBF );
+ newDBF->nFields = psDBF->nFields;
+ newDBF->nRecordLength = psDBF->nRecordLength;
+ newDBF->nHeaderLength = psDBF->nHeaderLength;
- newDBF = DBFOpen ( pszFilename, "rb+" );
- newDBF->bWriteEndOfFileChar = psDBF->bWriteEndOfFileChar;
+ if (psDBF->pszHeader)
+ {
+ newDBF->pszHeader =
+ STATIC_CAST(char *, malloc(XBASE_FLDHDR_SZ * psDBF->nFields));
+ memcpy(newDBF->pszHeader, psDBF->pszHeader,
+ XBASE_FLDHDR_SZ * psDBF->nFields);
+ }
- return ( newDBF );
+ newDBF->panFieldOffset =
+ STATIC_CAST(int *, malloc(sizeof(int) * psDBF->nFields));
+ memcpy(newDBF->panFieldOffset, psDBF->panFieldOffset,
+ sizeof(int) * psDBF->nFields);
+ newDBF->panFieldSize =
+ STATIC_CAST(int *, malloc(sizeof(int) * psDBF->nFields));
+ memcpy(newDBF->panFieldSize, psDBF->panFieldSize,
+ sizeof(int) * psDBF->nFields);
+ newDBF->panFieldDecimals =
+ STATIC_CAST(int *, malloc(sizeof(int) * psDBF->nFields));
+ memcpy(newDBF->panFieldDecimals, psDBF->panFieldDecimals,
+ sizeof(int) * psDBF->nFields);
+ newDBF->pachFieldType =
+ STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nFields));
+ memcpy(newDBF->pachFieldType, psDBF->pachFieldType,
+ sizeof(char) * psDBF->nFields);
+
+ newDBF->bNoHeader = TRUE;
+ newDBF->bUpdated = TRUE;
+ newDBF->bWriteEndOfFileChar = psDBF->bWriteEndOfFileChar;
+
+ DBFWriteHeader(newDBF);
+ DBFClose(newDBF);
+
+ newDBF = DBFOpen(pszFilename, "rb+");
+ newDBF->bWriteEndOfFileChar = psDBF->bWriteEndOfFileChar;
+
+ return (newDBF);
}
/************************************************************************/
@@ -1832,14 +1648,13 @@ DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename )
/* 'M' (Memo: 10 digits .DBT block ptr) */
/************************************************************************/
-char SHPAPI_CALL
-DBFGetNativeFieldType( DBFHandle psDBF, int iField )
+char SHPAPI_CALL DBFGetNativeFieldType(DBFHandle psDBF, int iField)
{
- if( iField >=0 && iField < psDBF->nFields )
+ if (iField >= 0 && iField < psDBF->nFields)
return psDBF->pachFieldType[iField];
- return ' ';
+ return ' ';
}
/************************************************************************/
@@ -1850,20 +1665,17 @@ DBFGetNativeFieldType( DBFHandle psDBF, int iField )
/* Contributed by Jim Matthews. */
/************************************************************************/
-int SHPAPI_CALL
-DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
-
+int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
{
- char name[XBASE_FLDNAME_LEN_READ+1];
- int i;
+ char name[XBASE_FLDNAME_LEN_READ + 1];
- for( i = 0; i < DBFGetFieldCount(psDBF); i++ )
+ for (int i = 0; i < DBFGetFieldCount(psDBF); i++)
{
- DBFGetFieldInfo( psDBF, i, name, SHPLIB_NULLPTR, SHPLIB_NULLPTR );
- if(!STRCASECMP(pszFieldName,name))
- return(i);
+ DBFGetFieldInfo(psDBF, i, name, SHPLIB_NULLPTR, SHPLIB_NULLPTR);
+ if (!STRCASECMP(pszFieldName, name))
+ return (i);
}
- return(-1);
+ return (-1);
}
/************************************************************************/
@@ -1873,24 +1685,23 @@ DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
/* it returns FALSE. */
/************************************************************************/
-int SHPAPI_CALL DBFIsRecordDeleted( DBFHandle psDBF, int iShape )
-
+int SHPAPI_CALL DBFIsRecordDeleted(DBFHandle psDBF, int iShape)
{
-/* -------------------------------------------------------------------- */
-/* Verify selection. */
-/* -------------------------------------------------------------------- */
- if( iShape < 0 || iShape >= psDBF->nRecords )
+ /* -------------------------------------------------------------------- */
+ /* Verify selection. */
+ /* -------------------------------------------------------------------- */
+ if (iShape < 0 || iShape >= psDBF->nRecords)
return TRUE;
-/* -------------------------------------------------------------------- */
-/* Have we read the record? */
-/* -------------------------------------------------------------------- */
- if( !DBFLoadRecord( psDBF, iShape ) )
+ /* -------------------------------------------------------------------- */
+ /* Have we read the record? */
+ /* -------------------------------------------------------------------- */
+ if (!DBFLoadRecord(psDBF, iShape))
return FALSE;
-/* -------------------------------------------------------------------- */
-/* '*' means deleted. */
-/* -------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+ /* '*' means deleted. */
+ /* -------------------------------------------------------------------- */
return psDBF->pszCurrentRecord[0] == '*';
}
@@ -1898,34 +1709,32 @@ int SHPAPI_CALL DBFIsRecordDeleted( DBFHandle psDBF, int iShape )
/* DBFMarkRecordDeleted() */
/************************************************************************/
-int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape,
- int bIsDeleted )
-
+int SHPAPI_CALL DBFMarkRecordDeleted(DBFHandle psDBF, int iShape,
+ int bIsDeleted)
{
- char chNewFlag;
-
-/* -------------------------------------------------------------------- */
-/* Verify selection. */
-/* -------------------------------------------------------------------- */
- if( iShape < 0 || iShape >= psDBF->nRecords )
+ /* -------------------------------------------------------------------- */
+ /* Verify selection. */
+ /* -------------------------------------------------------------------- */
+ if (iShape < 0 || iShape >= psDBF->nRecords)
return FALSE;
-/* -------------------------------------------------------------------- */
-/* Is this an existing record, but different than the last one */
-/* we accessed? */
-/* -------------------------------------------------------------------- */
- if( !DBFLoadRecord( psDBF, iShape ) )
+ /* -------------------------------------------------------------------- */
+ /* Is this an existing record, but different than the last one */
+ /* we accessed? */
+ /* -------------------------------------------------------------------- */
+ if (!DBFLoadRecord(psDBF, iShape))
return FALSE;
-/* -------------------------------------------------------------------- */
-/* Assign value, marking record as dirty if it changes. */
-/* -------------------------------------------------------------------- */
- if( bIsDeleted )
+ /* -------------------------------------------------------------------- */
+ /* Assign value, marking record as dirty if it changes. */
+ /* -------------------------------------------------------------------- */
+ char chNewFlag;
+ if (bIsDeleted)
chNewFlag = '*';
else
chNewFlag = ' ';
- if( psDBF->pszCurrentRecord[0] != chNewFlag )
+ if (psDBF->pszCurrentRecord[0] != chNewFlag)
{
psDBF->bCurrentRecordModified = TRUE;
psDBF->bUpdated = TRUE;
@@ -1939,10 +1748,9 @@ int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape,
/* DBFGetCodePage */
/************************************************************************/
-const char SHPAPI_CALL1(*)
-DBFGetCodePage(DBFHandle psDBF )
+const char SHPAPI_CALL1(*) DBFGetCodePage(DBFHandle psDBF)
{
- if( psDBF == SHPLIB_NULLPTR )
+ if (psDBF == SHPLIB_NULLPTR)
return SHPLIB_NULLPTR;
return psDBF->pszCodePage;
}
@@ -1953,109 +1761,110 @@ DBFGetCodePage(DBFHandle psDBF )
/* Remove a field from a .dbf file */
/************************************************************************/
-int SHPAPI_CALL
-DBFDeleteField(DBFHandle psDBF, int iField)
+int SHPAPI_CALL DBFDeleteField(DBFHandle psDBF, int iField)
{
- int nOldRecordLength, nOldHeaderLength;
- int nDeletedFieldOffset, nDeletedFieldSize;
- SAOffset nRecordOffset;
- char* pszRecord;
- int i, iRecord;
-
if (iField < 0 || iField >= psDBF->nFields)
return FALSE;
/* make sure that everything is written in .dbf */
- if( !DBFFlushRecord( psDBF ) )
+ if (!DBFFlushRecord(psDBF))
return FALSE;
/* get information about field to be deleted */
- nOldRecordLength = psDBF->nRecordLength;
- nOldHeaderLength = psDBF->nHeaderLength;
- nDeletedFieldOffset = psDBF->panFieldOffset[iField];
- nDeletedFieldSize = psDBF->panFieldSize[iField];
+ int nOldRecordLength = psDBF->nRecordLength;
+ int nOldHeaderLength = psDBF->nHeaderLength;
+ int nDeletedFieldOffset = psDBF->panFieldOffset[iField];
+ int nDeletedFieldSize = psDBF->panFieldSize[iField];
/* update fields info */
- for (i = iField + 1; i < psDBF->nFields; i++)
+ for (int i = iField + 1; i < psDBF->nFields; i++)
{
- psDBF->panFieldOffset[i-1] = psDBF->panFieldOffset[i] - nDeletedFieldSize;
- psDBF->panFieldSize[i-1] = psDBF->panFieldSize[i];
- psDBF->panFieldDecimals[i-1] = psDBF->panFieldDecimals[i];
- psDBF->pachFieldType[i-1] = psDBF->pachFieldType[i];
+ psDBF->panFieldOffset[i - 1] =
+ psDBF->panFieldOffset[i] - nDeletedFieldSize;
+ psDBF->panFieldSize[i - 1] = psDBF->panFieldSize[i];
+ psDBF->panFieldDecimals[i - 1] = psDBF->panFieldDecimals[i];
+ psDBF->pachFieldType[i - 1] = psDBF->pachFieldType[i];
}
/* resize fields arrays */
psDBF->nFields--;
- psDBF->panFieldOffset = STATIC_CAST(int *,
- SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ));
+ psDBF->panFieldOffset = STATIC_CAST(
+ int *, realloc(psDBF->panFieldOffset, sizeof(int) * psDBF->nFields));
- psDBF->panFieldSize = STATIC_CAST(int *,
- SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ));
+ psDBF->panFieldSize = STATIC_CAST(
+ int *, realloc(psDBF->panFieldSize, sizeof(int) * psDBF->nFields));
- psDBF->panFieldDecimals = STATIC_CAST(int *,
- SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ));
+ psDBF->panFieldDecimals = STATIC_CAST(
+ int *, realloc(psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields));
- psDBF->pachFieldType = STATIC_CAST(char *,
- SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields ));
+ psDBF->pachFieldType = STATIC_CAST(
+ char *, realloc(psDBF->pachFieldType, sizeof(char) * psDBF->nFields));
/* update header information */
psDBF->nHeaderLength -= XBASE_FLDHDR_SZ;
psDBF->nRecordLength -= nDeletedFieldSize;
/* overwrite field information in header */
- memmove(psDBF->pszHeader + iField*XBASE_FLDHDR_SZ,
- psDBF->pszHeader + (iField+1)*XBASE_FLDHDR_SZ,
- sizeof(char) * (psDBF->nFields - iField)*XBASE_FLDHDR_SZ);
+ memmove(psDBF->pszHeader + iField * XBASE_FLDHDR_SZ,
+ psDBF->pszHeader + (iField + 1) * XBASE_FLDHDR_SZ,
+ sizeof(char) * (psDBF->nFields - iField) * XBASE_FLDHDR_SZ);
- psDBF->pszHeader = STATIC_CAST(char *, SfRealloc(psDBF->pszHeader,
- psDBF->nFields*XBASE_FLDHDR_SZ));
+ psDBF->pszHeader = STATIC_CAST(
+ char *, realloc(psDBF->pszHeader, psDBF->nFields * XBASE_FLDHDR_SZ));
/* update size of current record appropriately */
- psDBF->pszCurrentRecord = STATIC_CAST(char *, SfRealloc(psDBF->pszCurrentRecord,
- psDBF->nRecordLength));
+ psDBF->pszCurrentRecord = STATIC_CAST(
+ char *, realloc(psDBF->pszCurrentRecord, psDBF->nRecordLength));
/* we're done if we're dealing with not yet created .dbf */
- if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
+ if (psDBF->bNoHeader && psDBF->nRecords == 0)
return TRUE;
/* force update of header with new header and record length */
psDBF->bNoHeader = TRUE;
- DBFUpdateHeader( psDBF );
+ DBFUpdateHeader(psDBF);
/* alloc record */
- pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * nOldRecordLength));
+ char *pszRecord =
+ STATIC_CAST(char *, malloc(sizeof(char) * nOldRecordLength));
/* shift records to their new positions */
- for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+ for (int iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
{
- nRecordOffset =
- nOldRecordLength * STATIC_CAST(SAOffset,iRecord) + nOldHeaderLength;
+ SAOffset nRecordOffset =
+ nOldRecordLength * STATIC_CAST(SAOffset, iRecord) +
+ nOldHeaderLength;
/* load record */
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ if (psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1, psDBF->fp) != 1)
+ {
+ free(pszRecord);
+ return FALSE;
+ }
- nRecordOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength;
+ nRecordOffset = psDBF->nRecordLength * STATIC_CAST(SAOffset, iRecord) +
+ psDBF->nHeaderLength;
/* move record in two steps */
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FWrite( pszRecord, nDeletedFieldOffset, 1, psDBF->fp );
- psDBF->sHooks.FWrite( pszRecord + nDeletedFieldOffset + nDeletedFieldSize,
- nOldRecordLength - nDeletedFieldOffset - nDeletedFieldSize,
- 1, psDBF->fp );
-
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ psDBF->sHooks.FWrite(pszRecord, nDeletedFieldOffset, 1, psDBF->fp);
+ psDBF->sHooks.FWrite(
+ pszRecord + nDeletedFieldOffset + nDeletedFieldSize,
+ nOldRecordLength - nDeletedFieldOffset - nDeletedFieldSize, 1,
+ psDBF->fp);
}
- if( psDBF->bWriteEndOfFileChar )
+ if (psDBF->bWriteEndOfFileChar)
{
char ch = END_OF_FILE_CHARACTER;
SAOffset nEOFOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength;
+ psDBF->nRecordLength * STATIC_CAST(SAOffset, psDBF->nRecords) +
+ psDBF->nHeaderLength;
- psDBF->sHooks.FSeek( psDBF->fp, nEOFOffset, 0 );
- psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nEOFOffset, 0);
+ psDBF->sHooks.FWrite(&ch, 1, 1, psDBF->fp);
}
/* TODO: truncate file */
@@ -2080,36 +1889,30 @@ DBFDeleteField(DBFHandle psDBF, int iField)
/* code of DBFReorderFields. */
/************************************************************************/
-int SHPAPI_CALL
-DBFReorderFields( DBFHandle psDBF, int* panMap )
+int SHPAPI_CALL DBFReorderFields(DBFHandle psDBF, const int *panMap)
{
- SAOffset nRecordOffset;
- int i, iRecord;
- int *panFieldOffsetNew;
- int *panFieldSizeNew;
- int *panFieldDecimalsNew;
- char *pachFieldTypeNew;
- char *pszHeaderNew;
- char *pszRecord;
- char *pszRecordNew;
-
- if ( psDBF->nFields == 0 )
+ if (psDBF->nFields == 0)
return TRUE;
/* make sure that everything is written in .dbf */
- if( !DBFFlushRecord( psDBF ) )
+ if (!DBFFlushRecord(psDBF))
return FALSE;
- /* a simple malloc() would be enough, but calloc() helps clang static analyzer */
- panFieldOffsetNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields));
- panFieldSizeNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields));
- panFieldDecimalsNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields));
- pachFieldTypeNew = STATIC_CAST(char *, calloc(sizeof(char), psDBF->nFields));
- pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ *
- psDBF->nFields));
+ /* a simple malloc() would be enough, but calloc() helps clang static
+ * analyzer */
+ int *panFieldOffsetNew =
+ STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields));
+ int *panFieldSizeNew =
+ STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields));
+ int *panFieldDecimalsNew =
+ STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields));
+ char *pachFieldTypeNew =
+ STATIC_CAST(char *, calloc(sizeof(char), psDBF->nFields));
+ char *pszHeaderNew = STATIC_CAST(
+ char *, malloc(sizeof(char) * XBASE_FLDHDR_SZ * psDBF->nFields));
/* shuffle fields definitions */
- for(i=0; i < psDBF->nFields; i++)
+ for (int i = 0; i < psDBF->nFields; i++)
{
panFieldSizeNew[i] = psDBF->panFieldSize[panMap[i]];
panFieldDecimalsNew[i] = psDBF->panFieldDecimals[panMap[i]];
@@ -2118,38 +1921,49 @@ DBFReorderFields( DBFHandle psDBF, int* panMap )
psDBF->pszHeader + panMap[i] * XBASE_FLDHDR_SZ, XBASE_FLDHDR_SZ);
}
panFieldOffsetNew[0] = 1;
- for(i=1; i < psDBF->nFields; i++)
+ for (int i = 1; i < psDBF->nFields; i++)
{
- panFieldOffsetNew[i] = panFieldOffsetNew[i - 1] + panFieldSizeNew[i - 1];
+ panFieldOffsetNew[i] =
+ panFieldOffsetNew[i - 1] + panFieldSizeNew[i - 1];
}
free(psDBF->pszHeader);
psDBF->pszHeader = pszHeaderNew;
+ bool errorAbort = false;
+
/* we're done if we're dealing with not yet created .dbf */
- if ( !(psDBF->bNoHeader && psDBF->nRecords == 0) )
+ if (!(psDBF->bNoHeader && psDBF->nRecords == 0))
{
/* force update of header with new header and record length */
psDBF->bNoHeader = TRUE;
- DBFUpdateHeader( psDBF );
+ DBFUpdateHeader(psDBF);
/* alloc record */
- pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
- pszRecordNew = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
+ char *pszRecord =
+ STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
+ char *pszRecordNew =
+ STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
/* shuffle fields in records */
- for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+ for (int iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
{
- nRecordOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength;
+ const SAOffset nRecordOffset =
+ psDBF->nRecordLength * STATIC_CAST(SAOffset, iRecord) +
+ psDBF->nHeaderLength;
/* load record */
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FRead( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ if (psDBF->sHooks.FRead(pszRecord, psDBF->nRecordLength, 1,
+ psDBF->fp) != 1)
+ {
+ errorAbort = true;
+ break;
+ }
pszRecordNew[0] = pszRecord[0];
- for(i=0; i < psDBF->nFields; i++)
+ for (int i = 0; i < psDBF->nFields; i++)
{
memcpy(pszRecordNew + panFieldOffsetNew[i],
pszRecord + psDBF->panFieldOffset[panMap[i]],
@@ -2157,8 +1971,9 @@ DBFReorderFields( DBFHandle psDBF, int* panMap )
}
/* write record */
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FWrite( pszRecordNew, psDBF->nRecordLength, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ psDBF->sHooks.FWrite(pszRecordNew, psDBF->nRecordLength, 1,
+ psDBF->fp);
}
/* free record */
@@ -2166,6 +1981,18 @@ DBFReorderFields( DBFHandle psDBF, int* panMap )
free(pszRecordNew);
}
+ if (errorAbort)
+ {
+ free(panFieldOffsetNew);
+ free(panFieldSizeNew);
+ free(panFieldDecimalsNew);
+ free(pachFieldTypeNew);
+ psDBF->nCurrentRecord = -1;
+ psDBF->bCurrentRecordModified = FALSE;
+ psDBF->bUpdated = FALSE;
+ return FALSE;
+ }
+
free(psDBF->panFieldOffset);
free(psDBF->panFieldSize);
free(psDBF->panFieldDecimals);
@@ -2173,7 +2000,7 @@ DBFReorderFields( DBFHandle psDBF, int* panMap )
psDBF->panFieldOffset = panFieldOffsetNew;
psDBF->panFieldSize = panFieldSizeNew;
- psDBF->panFieldDecimals =panFieldDecimalsNew;
+ psDBF->panFieldDecimals = panFieldDecimalsNew;
psDBF->pachFieldType = pachFieldTypeNew;
psDBF->nCurrentRecord = -1;
@@ -2183,71 +2010,59 @@ DBFReorderFields( DBFHandle psDBF, int* panMap )
return TRUE;
}
-
/************************************************************************/
/* DBFAlterFieldDefn() */
/* */
/* Alter a field definition in a .dbf file */
/************************************************************************/
-int SHPAPI_CALL
-DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
- char chType, int nWidth, int nDecimals )
+int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField,
+ const char *pszFieldName, char chType,
+ int nWidth, int nDecimals)
{
- int i;
- int iRecord;
- int nOffset;
- int nOldWidth;
- int nOldRecordLength;
- SAOffset nRecordOffset;
- char* pszFInfo;
- char chOldType;
- int bIsNULL;
- char chFieldFill;
-
if (iField < 0 || iField >= psDBF->nFields)
return FALSE;
/* make sure that everything is written in .dbf */
- if( !DBFFlushRecord( psDBF ) )
+ if (!DBFFlushRecord(psDBF))
return FALSE;
- chFieldFill = DBFGetNullCharacter(chType);
+ const char chFieldFill = DBFGetNullCharacter(chType);
- chOldType = psDBF->pachFieldType[iField];
- nOffset = psDBF->panFieldOffset[iField];
- nOldWidth = psDBF->panFieldSize[iField];
- nOldRecordLength = psDBF->nRecordLength;
+ const char chOldType = psDBF->pachFieldType[iField];
+ const int nOffset = psDBF->panFieldOffset[iField];
+ const int nOldWidth = psDBF->panFieldSize[iField];
+ const int nOldRecordLength = psDBF->nRecordLength;
-/* -------------------------------------------------------------------- */
-/* Do some checking to ensure we can add records to this file. */
-/* -------------------------------------------------------------------- */
- if( nWidth < 1 )
+ /* -------------------------------------------------------------------- */
+ /* Do some checking to ensure we can add records to this file. */
+ /* -------------------------------------------------------------------- */
+ if (nWidth < 1)
return -1;
- if( nWidth > XBASE_FLD_MAX_WIDTH )
+ if (nWidth > XBASE_FLD_MAX_WIDTH)
nWidth = XBASE_FLD_MAX_WIDTH;
-/* -------------------------------------------------------------------- */
-/* Assign the new field information fields. */
-/* -------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+ /* Assign the new field information fields. */
+ /* -------------------------------------------------------------------- */
psDBF->panFieldSize[iField] = nWidth;
psDBF->panFieldDecimals[iField] = nDecimals;
psDBF->pachFieldType[iField] = chType;
-/* -------------------------------------------------------------------- */
-/* Update the header information. */
-/* -------------------------------------------------------------------- */
- pszFInfo = psDBF->pszHeader + XBASE_FLDHDR_SZ * iField;
+ /* -------------------------------------------------------------------- */
+ /* Update the header information. */
+ /* -------------------------------------------------------------------- */
+ char *pszFInfo = psDBF->pszHeader + XBASE_FLDHDR_SZ * iField;
- for( i = 0; i < XBASE_FLDHDR_SZ; i++ )
+ for (int i = 0; i < XBASE_FLDHDR_SZ; i++)
pszFInfo[i] = '\0';
- strncpy( pszFInfo, pszFieldName, XBASE_FLDNAME_LEN_WRITE );
+ strncpy(pszFInfo, pszFieldName, XBASE_FLDNAME_LEN_WRITE);
pszFInfo[11] = psDBF->pachFieldType[iField];
- if( chType == 'C' )
+ if (chType == 'C')
{
pszFInfo[16] = STATIC_CAST(unsigned char, nWidth % 256);
pszFInfo[17] = STATIC_CAST(unsigned char, nWidth / 256);
@@ -2258,60 +2073,71 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
pszFInfo[17] = STATIC_CAST(unsigned char, nDecimals);
}
-/* -------------------------------------------------------------------- */
-/* Update offsets */
-/* -------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+ /* Update offsets */
+ /* -------------------------------------------------------------------- */
if (nWidth != nOldWidth)
{
- for (i = iField + 1; i < psDBF->nFields; i++)
- psDBF->panFieldOffset[i] += nWidth - nOldWidth;
+ for (int i = iField + 1; i < psDBF->nFields; i++)
+ psDBF->panFieldOffset[i] += nWidth - nOldWidth;
psDBF->nRecordLength += nWidth - nOldWidth;
- psDBF->pszCurrentRecord = STATIC_CAST(char *, SfRealloc(psDBF->pszCurrentRecord,
- psDBF->nRecordLength));
+ psDBF->pszCurrentRecord = STATIC_CAST(
+ char *, realloc(psDBF->pszCurrentRecord, psDBF->nRecordLength));
}
/* we're done if we're dealing with not yet created .dbf */
- if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
+ if (psDBF->bNoHeader && psDBF->nRecords == 0)
return TRUE;
/* force update of header with new header and record length */
psDBF->bNoHeader = TRUE;
- DBFUpdateHeader( psDBF );
+ DBFUpdateHeader(psDBF);
+
+ bool errorAbort = false;
if (nWidth < nOldWidth || (nWidth == nOldWidth && chType != chOldType))
{
- char* pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * nOldRecordLength));
- char* pszOldField = STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1)));
+ char *pszRecord =
+ STATIC_CAST(char *, malloc(sizeof(char) * nOldRecordLength));
+ char *pszOldField =
+ STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1)));
/* cppcheck-suppress uninitdata */
pszOldField[nOldWidth] = 0;
/* move records to their new positions */
- for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+ for (int iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
{
- nRecordOffset =
- nOldRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength;
+ SAOffset nRecordOffset =
+ nOldRecordLength * STATIC_CAST(SAOffset, iRecord) +
+ psDBF->nHeaderLength;
/* load record */
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ if (psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1,
+ psDBF->fp) != 1)
+ {
+ errorAbort = true;
+ break;
+ }
memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
- bIsNULL = DBFIsValueNULL( chOldType, pszOldField );
+ const bool bIsNULL = DBFIsValueNULL(chOldType, pszOldField);
if (nWidth != nOldWidth)
{
- if ((chOldType == 'N' || chOldType == 'F' || chOldType == 'D') && pszOldField[0] == ' ')
+ if ((chOldType == 'N' || chOldType == 'F' ||
+ chOldType == 'D') &&
+ pszOldField[0] == ' ')
{
/* Strip leading spaces when truncating a numeric field */
- memmove( pszRecord + nOffset,
- pszRecord + nOffset + nOldWidth - nWidth,
- nWidth );
+ memmove(pszRecord + nOffset,
+ pszRecord + nOffset + nOldWidth - nWidth, nWidth);
}
if (nOffset + nOldWidth < nOldRecordLength)
{
- memmove( pszRecord + nOffset + nWidth,
+ memmove(pszRecord + nOffset + nWidth,
pszRecord + nOffset + nOldWidth,
nOldRecordLength - (nOffset + nOldWidth));
}
@@ -2320,26 +2146,28 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
/* Convert null value to the appropriate value of the new type */
if (bIsNULL)
{
- memset( pszRecord + nOffset, chFieldFill, nWidth);
+ memset(pszRecord + nOffset, chFieldFill, nWidth);
}
nRecordOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength;
+ psDBF->nRecordLength * STATIC_CAST(SAOffset, iRecord) +
+ psDBF->nHeaderLength;
/* write record */
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ psDBF->sHooks.FWrite(pszRecord, psDBF->nRecordLength, 1, psDBF->fp);
}
- if( psDBF->bWriteEndOfFileChar )
+ if (!errorAbort && psDBF->bWriteEndOfFileChar)
{
char ch = END_OF_FILE_CHARACTER;
- nRecordOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength;
+ SAOffset nRecordOffset =
+ psDBF->nRecordLength * STATIC_CAST(SAOffset, psDBF->nRecords) +
+ psDBF->nHeaderLength;
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ psDBF->sHooks.FWrite(&ch, 1, 1, psDBF->fp);
}
/* TODO: truncate file */
@@ -2348,76 +2176,95 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
}
else if (nWidth > nOldWidth)
{
- char* pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
- char* pszOldField = STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1)));
+ char *pszRecord =
+ STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
+ char *pszOldField =
+ STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1)));
/* cppcheck-suppress uninitdata */
pszOldField[nOldWidth] = 0;
/* move records to their new positions */
- for (iRecord = psDBF->nRecords - 1; iRecord >= 0; iRecord--)
+ for (int iRecord = psDBF->nRecords - 1; iRecord >= 0; iRecord--)
{
- nRecordOffset =
- nOldRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength;
+ SAOffset nRecordOffset =
+ nOldRecordLength * STATIC_CAST(SAOffset, iRecord) +
+ psDBF->nHeaderLength;
/* load record */
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ if (psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1,
+ psDBF->fp) != 1)
+ {
+ errorAbort = true;
+ break;
+ }
memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
- bIsNULL = DBFIsValueNULL( chOldType, pszOldField );
+ const bool bIsNULL = DBFIsValueNULL(chOldType, pszOldField);
if (nOffset + nOldWidth < nOldRecordLength)
{
- memmove( pszRecord + nOffset + nWidth,
- pszRecord + nOffset + nOldWidth,
- nOldRecordLength - (nOffset + nOldWidth));
+ memmove(pszRecord + nOffset + nWidth,
+ pszRecord + nOffset + nOldWidth,
+ nOldRecordLength - (nOffset + nOldWidth));
}
/* Convert null value to the appropriate value of the new type */
if (bIsNULL)
{
- memset( pszRecord + nOffset, chFieldFill, nWidth);
+ memset(pszRecord + nOffset, chFieldFill, nWidth);
}
else
{
if ((chOldType == 'N' || chOldType == 'F'))
{
/* Add leading spaces when expanding a numeric field */
- memmove( pszRecord + nOffset + nWidth - nOldWidth,
- pszRecord + nOffset, nOldWidth );
- memset( pszRecord + nOffset, ' ', nWidth - nOldWidth );
+ memmove(pszRecord + nOffset + nWidth - nOldWidth,
+ pszRecord + nOffset, nOldWidth);
+ memset(pszRecord + nOffset, ' ', nWidth - nOldWidth);
}
else
{
/* Add trailing spaces */
- memset(pszRecord + nOffset + nOldWidth, ' ', nWidth - nOldWidth);
+ memset(pszRecord + nOffset + nOldWidth, ' ',
+ nWidth - nOldWidth);
}
}
nRecordOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength;
+ psDBF->nRecordLength * STATIC_CAST(SAOffset, iRecord) +
+ psDBF->nHeaderLength;
/* write record */
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ psDBF->sHooks.FWrite(pszRecord, psDBF->nRecordLength, 1, psDBF->fp);
}
- if( psDBF->bWriteEndOfFileChar )
+ if (!errorAbort && psDBF->bWriteEndOfFileChar)
{
char ch = END_OF_FILE_CHARACTER;
- nRecordOffset =
- psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength;
+ SAOffset nRecordOffset =
+ psDBF->nRecordLength * STATIC_CAST(SAOffset, psDBF->nRecords) +
+ psDBF->nHeaderLength;
- psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
- psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp );
+ psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
+ psDBF->sHooks.FWrite(&ch, 1, 1, psDBF->fp);
}
free(pszRecord);
free(pszOldField);
}
+ if (errorAbort)
+ {
+ psDBF->nCurrentRecord = -1;
+ psDBF->bCurrentRecordModified = TRUE;
+ psDBF->bUpdated = FALSE;
+
+ return FALSE;
+ }
psDBF->nCurrentRecord = -1;
psDBF->bCurrentRecordModified = FALSE;
psDBF->bUpdated = TRUE;
@@ -2429,7 +2276,7 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
/* DBFSetWriteEndOfFileChar() */
/************************************************************************/
-void SHPAPI_CALL DBFSetWriteEndOfFileChar( DBFHandle psDBF, int bWriteFlag )
+void SHPAPI_CALL DBFSetWriteEndOfFileChar(DBFHandle psDBF, int bWriteFlag)
{
psDBF->bWriteEndOfFileChar = bWriteFlag;
}
diff --git a/shapelib/safileio.c b/shapelib/safileio.c
index d2c7f581c..b63a3933a 100644
--- a/shapelib/safileio.c
+++ b/shapelib/safileio.c
@@ -1,5 +1,4 @@
/******************************************************************************
- * $Id: safileio.c,v 1.6 2018-06-15 19:56:32 erouault Exp $
*
* Project: Shapelib
* Purpose: Default implementation of file io based on stdio.
@@ -8,223 +7,122 @@
******************************************************************************
* Copyright (c) 2007, Frank Warmerdam
*
- * This software is available under the following "MIT Style" license,
- * or at the option of the licensee under the LGPL (see COPYING). This
- * option is discussed in more detail in shapelib.html.
- *
- * --
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
+ * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
******************************************************************************
*
- * $Log: safileio.c,v $
- * Revision 1.6 2018-06-15 19:56:32 erouault
- * * safileio.c: remove duplicate test. Patch by Jaroslav Fojtik.
- * Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2744
- *
- * Revision 1.5 2016-12-05 12:44:05 erouault
- * * Major overhaul of Makefile build system to use autoconf/automake.
- *
- * * Warning fixes in contrib/
- *
- * Revision 1.4 2008-01-16 20:05:14 bram
- * Add file hooks that accept UTF-8 encoded filenames on some platforms. Use SASetupUtf8Hooks
- * tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability. Currently, this
- * is only available on the Windows platform that decodes the UTF-8 filenames to wide
- * character strings and feeds them to _wfopen and _wremove.
- *
- * Revision 1.3 2007/12/18 18:28:11 bram
- * - create hook for client specific atof (bugzilla ticket 1615)
- * - check for NULL handle before closing cpCPG file, and close after reading.
- *
- * Revision 1.2 2007/12/15 20:25:30 bram
- * dbfopen.c now reads the Code Page information from the DBF file, and exports
- * this information as a string through the DBFGetCodePage function. This is
- * either the number from the LDID header field ("LDID/") or as the
- * content of an accompanying .CPG file. When creating a DBF file, the code can
- * be set using DBFCreateEx.
- *
- * Revision 1.1 2007/12/06 06:56:41 fwarmerdam
- * new
- *
*/
#include "shapefil.h"
+#include
#include
#include
-#include
+#include
#include
#include
-#include
-
-SHP_CVSID("$Id: safileio.c,v 1.6 2018-06-15 19:56:32 erouault Exp $");
#ifdef SHPAPI_UTF8_HOOKS
-# ifdef SHPAPI_WINDOWS
-# define WIN32_LEAN_AND_MEAN
-# define NOMINMAX
-# include
-# pragma comment(lib, "kernel32.lib")
-# endif
+#ifdef SHPAPI_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include
+#pragma comment(lib, "kernel32.lib")
+#endif
#endif
-/************************************************************************/
-/* SADFOpen() */
-/************************************************************************/
-
-SAFile SADFOpen( const char *pszFilename, const char *pszAccess )
-
+static SAFile SADFOpen(const char *pszFilename, const char *pszAccess,
+ void *pvUserData)
{
- return (SAFile) fopen( pszFilename, pszAccess );
+ (void)pvUserData;
+ return (SAFile)fopen(pszFilename, pszAccess);
}
-/************************************************************************/
-/* SADFRead() */
-/************************************************************************/
-
-SAOffset SADFRead( void *p, SAOffset size, SAOffset nmemb, SAFile file )
-
+static SAOffset SADFRead(void *p, SAOffset size, SAOffset nmemb, SAFile file)
{
- return (SAOffset) fread( p, (size_t) size, (size_t) nmemb,
- (FILE *) file );
+ return (SAOffset)fread(p, (size_t)size, (size_t)nmemb, (FILE *)file);
}
-/************************************************************************/
-/* SADFWrite() */
-/************************************************************************/
-
-SAOffset SADFWrite( void *p, SAOffset size, SAOffset nmemb, SAFile file )
-
+static SAOffset SADFWrite(const void *p, SAOffset size, SAOffset nmemb,
+ SAFile file)
{
- return (SAOffset) fwrite( p, (size_t) size, (size_t) nmemb,
- (FILE *) file );
+ return (SAOffset)fwrite(p, (size_t)size, (size_t)nmemb, (FILE *)file);
}
-/************************************************************************/
-/* SADFSeek() */
-/************************************************************************/
-
-SAOffset SADFSeek( SAFile file, SAOffset offset, int whence )
-
+static SAOffset SADFSeek(SAFile file, SAOffset offset, int whence)
{
- return (SAOffset) fseek( (FILE *) file, (long) offset, whence );
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ return (SAOffset)_fseeki64((FILE *)file, (__int64)offset, whence);
+#else
+ return (SAOffset)fseek((FILE *)file, (long)offset, whence);
+#endif
}
-/************************************************************************/
-/* SADFTell() */
-/************************************************************************/
-
-SAOffset SADFTell( SAFile file )
-
+static SAOffset SADFTell(SAFile file)
{
- return (SAOffset) ftell( (FILE *) file );
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ return (SAOffset)_ftelli64((FILE *)file);
+#else
+ return (SAOffset)ftell((FILE *)file);
+#endif
}
-/************************************************************************/
-/* SADFFlush() */
-/************************************************************************/
-
-int SADFFlush( SAFile file )
-
+static int SADFFlush(SAFile file)
{
- return fflush( (FILE *) file );
+ return fflush((FILE *)file);
}
-/************************************************************************/
-/* SADFClose() */
-/************************************************************************/
-
-int SADFClose( SAFile file )
-
+static int SADFClose(SAFile file)
{
- return fclose( (FILE *) file );
+ return fclose((FILE *)file);
}
-/************************************************************************/
-/* SADFClose() */
-/************************************************************************/
-
-int SADRemove( const char *filename )
-
+static int SADRemove(const char *filename, void *pvUserData)
{
- return remove( filename );
+ (void)pvUserData;
+ return remove(filename);
}
-/************************************************************************/
-/* SADError() */
-/************************************************************************/
-
-void SADError( const char *message )
-
+static void SADError(const char *message)
{
- fprintf( stderr, "%s\n", message );
+ fprintf(stderr, "%s\n", message);
}
-/************************************************************************/
-/* SASetupDefaultHooks() */
-/************************************************************************/
-
-void SASetupDefaultHooks( SAHooks *psHooks )
-
+void SASetupDefaultHooks(SAHooks *psHooks)
{
- psHooks->FOpen = SADFOpen;
- psHooks->FRead = SADFRead;
- psHooks->FWrite = SADFWrite;
- psHooks->FSeek = SADFSeek;
- psHooks->FTell = SADFTell;
- psHooks->FFlush = SADFFlush;
- psHooks->FClose = SADFClose;
- psHooks->Remove = SADRemove;
-
- psHooks->Error = SADError;
- psHooks->Atof = atof;
+ psHooks->FOpen = SADFOpen;
+ psHooks->FRead = SADFRead;
+ psHooks->FWrite = SADFWrite;
+ psHooks->FSeek = SADFSeek;
+ psHooks->FTell = SADFTell;
+ psHooks->FFlush = SADFFlush;
+ psHooks->FClose = SADFClose;
+ psHooks->Remove = SADRemove;
+
+ psHooks->Error = SADError;
+ psHooks->Atof = atof;
+ psHooks->pvUserData = NULL;
}
-
-
-
#ifdef SHPAPI_WINDOWS
-/************************************************************************/
-/* Utf8ToWideChar */
-/************************************************************************/
-
-const wchar_t* Utf8ToWideChar( const char *pszFilename )
+static wchar_t *Utf8ToWideChar(const char *pszFilename)
{
- int nMulti, nWide;
- wchar_t *pwszFileName;
-
- nMulti = strlen(pszFilename) + 1;
- nWide = MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, 0, 0);
- if( nWide == 0 )
+ const int nMulti = (int)strlen(pszFilename) + 1;
+ const int nWide =
+ MultiByteToWideChar(CP_UTF8, 0, pszFilename, nMulti, 0, 0);
+ if (nWide == 0)
{
return NULL;
}
- pwszFileName = (wchar_t*) malloc(nWide * sizeof(wchar_t));
- if ( pwszFileName == NULL )
+ wchar_t *pwszFileName = (wchar_t *)malloc(nWide * sizeof(wchar_t));
+ if (pwszFileName == NULL)
{
return NULL;
}
- if( MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, pwszFileName, nWide ) == 0 )
+ if (MultiByteToWideChar(CP_UTF8, 0, pszFilename, nMulti, pwszFileName,
+ nWide) == 0)
{
- free( pwszFileName );
+ free(pwszFileName);
return NULL;
}
return pwszFileName;
@@ -234,62 +132,51 @@ const wchar_t* Utf8ToWideChar( const char *pszFilename )
/* SAUtf8WFOpen */
/************************************************************************/
-SAFile SAUtf8WFOpen( const char *pszFilename, const char *pszAccess )
+SAFile SAUtf8WFOpen(const char *pszFilename, const char *pszAccess)
{
SAFile file = NULL;
- const wchar_t *pwszFileName, *pwszAccess;
- pwszFileName = Utf8ToWideChar( pszFilename );
- pwszAccess = Utf8ToWideChar( pszAccess );
- if( pwszFileName != NULL && pwszAccess != NULL)
+ wchar_t *pwszFileName = Utf8ToWideChar(pszFilename);
+ wchar_t *pwszAccess = Utf8ToWideChar(pszAccess);
+ if (pwszFileName != NULL && pwszAccess != NULL)
{
- file = (SAFile) _wfopen( pwszFileName, pwszAccess );
+ file = (SAFile)_wfopen(pwszFileName, pwszAccess);
}
- free ((wchar_t*) pwszFileName);
- free ((wchar_t*) pwszAccess);
+ free(pwszFileName);
+ free(pwszAccess);
return file;
}
-/************************************************************************/
-/* SAUtf8WRemove() */
-/************************************************************************/
-
-int SAUtf8WRemove( const char *pszFilename )
+int SAUtf8WRemove(const char *pszFilename)
{
- const wchar_t *pwszFileName = Utf8ToWideChar( pszFilename );
- int rc = -1;
- if( pwszFileName != NULL )
+ wchar_t *pwszFileName = Utf8ToWideChar(pszFilename);
+ int rc = -1;
+ if (pwszFileName != NULL)
{
- rc = _wremove( pwszFileName );
+ rc = _wremove(pwszFileName);
}
- free ((wchar_t*) pwszFileName);
+ free(pwszFileName);
return rc;
}
#endif
#ifdef SHPAPI_UTF8_HOOKS
-
-/************************************************************************/
-/* SASetupUtf8Hooks() */
-/************************************************************************/
-
-void SASetupUtf8Hooks( SAHooks *psHooks )
-{
-#ifdef SHPAPI_WINDOWS
- psHooks->FOpen = SAUtf8WFOpen;
- psHooks->Remove = SAUtf8WRemove;
-#else
-# error "no implementations of UTF-8 hooks available for this platform"
+#ifndef SHPAPI_WINDOWS
+#error "no implementations of UTF-8 hooks available for this platform"
#endif
- psHooks->FRead = SADFRead;
- psHooks->FWrite = SADFWrite;
- psHooks->FSeek = SADFSeek;
- psHooks->FTell = SADFTell;
- psHooks->FFlush = SADFFlush;
- psHooks->FClose = SADFClose;
- psHooks->Error = SADError;
- psHooks->Atof = atof;
+void SASetupUtf8Hooks(SAHooks *psHooks)
+{
+ psHooks->FOpen = SAUtf8WFOpen;
+ psHooks->Remove = SAUtf8WRemove;
+ psHooks->FRead = SADFRead;
+ psHooks->FWrite = SADFWrite;
+ psHooks->FSeek = SADFSeek;
+ psHooks->FTell = SADFTell;
+ psHooks->FFlush = SADFFlush;
+ psHooks->FClose = SADFClose;
+
+ psHooks->Error = SADError;
+ psHooks->Atof = atof;
}
-
#endif
diff --git a/shapelib/shapefil.h b/shapelib/shapefil.h
index 199964d42..2328f15cc 100644
--- a/shapelib/shapefil.h
+++ b/shapelib/shapefil.h
@@ -2,7 +2,6 @@
#define SHAPEFILE_H_INCLUDED
/******************************************************************************
- * $Id: shapefil.h,v 1.56 2018-08-16 15:39:07 erouault Exp $
*
* Project: Shapelib
* Purpose: Primary include file for Shapelib.
@@ -10,185 +9,41 @@
*
******************************************************************************
* Copyright (c) 1999, Frank Warmerdam
- * Copyright (c) 2012-2016, Even Rouault
+ * Copyright (c) 2012-2016, Even Rouault
*
- * This software is available under the following "MIT Style" license,
- * or at the option of the licensee under the LGPL (see COPYING). This
- * option is discussed in more detail in shapelib.html.
- *
- * --
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
+ * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
******************************************************************************
*
- * $Log: shapefil.h,v $
- * Revision 1.56 2018-08-16 15:39:07 erouault
- * * shpopen.c, dbfopen.c, shptree.c, sbnsearch.c: resyc with GDAL
- * internal shapelib. Mostly to allow building those files as C++
- * without warning. Also add FTDate entry in DBFFieldType
- * (see https://github.com/OSGeo/gdal/pull/308). And some other
- * code cleanups
- *
- * Revision 1.55 2016-12-05 18:44:08 erouault
- * * dbfopen.c, shapefil.h: write DBF end-of-file character 0x1A by default.
- * This behaviour can be controlled with the DBFSetWriteEndOfFileChar()
- * function.
- *
- * Revision 1.54 2016-12-05 12:44:05 erouault
- * * Major overhaul of Makefile build system to use autoconf/automake.
- *
- * * Warning fixes in contrib/
- *
- * Revision 1.53 2016-12-04 15:30:15 erouault
- * * shpopen.c, dbfopen.c, shptree.c, shapefil.h: resync with
- * GDAL Shapefile driver. Mostly cleanups. SHPObject and DBFInfo
- * structures extended with new members. New functions:
- * DBFSetLastModifiedDate, SHPOpenLLEx, SHPRestoreSHX,
- * SHPSetFastModeReadObject
- *
- * * sbnsearch.c: new file to implement original ESRI .sbn spatial
- * index reading. (no write support). New functions:
- * SBNOpenDiskTree, SBNCloseDiskTree, SBNSearchDiskTree,
- * SBNSearchDiskTreeInteger, SBNSearchFreeIds
- *
- * * Makefile, makefile.vc, CMakeLists.txt, shapelib.def: updates
- * with new file and symbols.
- *
- * * commit: helper script to cvs commit
- *
- * Revision 1.52 2011-12-11 22:26:46 fwarmerdam
- * upgrade .qix access code to use SAHooks (gdal #3365)
- *
- * Revision 1.51 2011-07-24 05:59:25 fwarmerdam
- * minimize use of CPLError in favor of SAHooks.Error()
- *
- * Revision 1.50 2011-05-13 17:35:17 fwarmerdam
- * added DBFReorderFields() and DBFAlterFields() functions (from Even)
- *
- * Revision 1.49 2011-04-16 14:38:21 fwarmerdam
- * avoid warnings with gcc on SHP_CVSID
- *
- * Revision 1.48 2010-08-27 23:42:52 fwarmerdam
- * add SHPAPI_CALL attribute in code
- *
- * Revision 1.47 2010-01-28 11:34:34 fwarmerdam
- * handle the shape file length limits more gracefully (#3236)
- *
- * Revision 1.46 2008-11-12 14:28:15 fwarmerdam
- * DBFCreateField() now works on files with records
- *
- * Revision 1.45 2008/11/11 17:47:10 fwarmerdam
- * added DBFDeleteField() function
- *
- * Revision 1.44 2008/01/16 20:05:19 bram
- * Add file hooks that accept UTF-8 encoded filenames on some platforms. Use SASetupUtf8Hooks
- * tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability. Currently, this
- * is only available on the Windows platform that decodes the UTF-8 filenames to wide
- * character strings and feeds them to _wfopen and _wremove.
- *
- * Revision 1.43 2008/01/10 16:35:30 fwarmerdam
- * avoid _ prefix on #defined symbols (bug 1840)
- *
- * Revision 1.42 2007/12/18 18:28:14 bram
- * - create hook for client specific atof (bugzilla ticket 1615)
- * - check for NULL handle before closing cpCPG file, and close after reading.
- *
- * Revision 1.41 2007/12/15 20:25:32 bram
- * dbfopen.c now reads the Code Page information from the DBF file, and exports
- * this information as a string through the DBFGetCodePage function. This is
- * either the number from the LDID header field ("LDID/") or as the
- * content of an accompanying .CPG file. When creating a DBF file, the code can
- * be set using DBFCreateEx.
- *
- * Revision 1.40 2007/12/06 07:00:25 fwarmerdam
- * dbfopen now using SAHooks for fileio
- *
- * Revision 1.39 2007/12/04 20:37:56 fwarmerdam
- * preliminary implementation of hooks api for io and errors
- *
- * Revision 1.38 2007/11/21 22:39:56 fwarmerdam
- * close shx file in readonly mode (GDAL #1956)
- *
- * Revision 1.37 2007/10/27 03:31:14 fwarmerdam
- * limit default depth of tree to 12 levels (gdal ticket #1594)
- *
- * Revision 1.36 2007/09/10 23:33:15 fwarmerdam
- * Upstreamed support for visibility flag in SHPAPI_CALL for the needs
- * of GDAL (gdal ticket #1810).
- *
- * Revision 1.35 2007/09/03 19:48:10 fwarmerdam
- * move DBFReadAttribute() static dDoubleField into dbfinfo
- *
- * Revision 1.34 2006/06/17 15:33:32 fwarmerdam
- * added pszWorkField - bug 1202 (rso)
- *
- * Revision 1.33 2006/02/15 01:14:30 fwarmerdam
- * added DBFAddNativeFieldType
- *
- * Revision 1.32 2006/01/26 15:07:32 fwarmerdam
- * add bMeasureIsUsed flag from Craig Bruce: Bug 1249
- *
- * Revision 1.31 2006/01/05 01:27:27 fwarmerdam
- * added dbf deletion mark/fetch
- *
- * Revision 1.30 2005/01/03 22:30:13 fwarmerdam
- * added support for saved quadtrees
- *
- * Revision 1.29 2004/09/26 20:09:35 fwarmerdam
- * avoid rcsid warnings
- *
- * Revision 1.28 2003/12/29 06:02:18 fwarmerdam
- * added cpl_error.h option
- *
- * Revision 1.27 2003/04/21 18:30:37 warmerda
- * added header write/update public methods
- *
- * Revision 1.26 2002/09/29 00:00:08 warmerda
- * added FTLogical and logical attribute read/write calls
- *
- * Revision 1.25 2002/05/07 13:46:30 warmerda
- * added DBFWriteAttributeDirectly().
- *
- * Revision 1.24 2002/04/10 16:59:54 warmerda
- * added SHPRewindObject
- *
- * Revision 1.23 2002/01/15 14:36:07 warmerda
- * updated email address
- *
- * Revision 1.22 2002/01/15 14:32:00 warmerda
- * try to improve SHPAPI_CALL docs
*/
#include
-#ifdef USE_DBMALLOC
-#include
-#endif
-
#ifdef USE_CPL
#include "cpl_conv.h"
#endif
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
+/************************************************************************/
+/* Version related macros (added in 1.6.0) */
+/************************************************************************/
+
+#define SHAPELIB_VERSION_MAJOR 1
+#define SHAPELIB_VERSION_MINOR 6
+#define SHAPELIB_VERSION_MICRO 0
+
+#define SHAPELIB_MAKE_VERSION_NUMBER(major, minor, micro) \
+ ((major) * 10000 + (minor) * 100 + (micro))
+
+#define SHAPELIB_VERSION_NUMBER \
+ SHAPELIB_MAKE_VERSION_NUMBER(SHAPELIB_VERSION_MAJOR, SHAPELIB_VERSION_MINOR, SHAPELIB_VERSION_MICRO)
+
+#define SHAPELIB_AT_LEAST(major, minor, micro) \
+ (SHAPELIB_VERSION_NUMBER >= SHAPELIB_MAKE_VERSION_NUMBER(major, minor, micro))
+
/************************************************************************/
/* Configuration options. */
/************************************************************************/
@@ -206,66 +61,51 @@ extern "C" {
/* -------------------------------------------------------------------- */
#define DISABLE_MULTIPATCH_MEASURE
-/* -------------------------------------------------------------------- */
-/* SHPAPI_CALL */
-/* */
-/* The following two macros are present to allow forcing */
-/* various calling conventions on the Shapelib API. */
-/* */
-/* To force __stdcall conventions (needed to call Shapelib */
-/* from Visual Basic and/or Dephi I believe) the makefile could */
-/* be modified to define: */
-/* */
-/* /DSHPAPI_CALL=__stdcall */
-/* */
-/* If it is desired to force export of the Shapelib API without */
-/* using the shapelib.def file, use the following definition. */
-/* */
-/* /DSHAPELIB_DLLEXPORT */
-/* */
-/* To get both at once it will be necessary to hack this */
-/* include file to define: */
-/* */
-/* #define SHPAPI_CALL __declspec(dllexport) __stdcall */
-/* #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall */
-/* */
-/* The complexity of the situation is partly caused by the */
-/* peculiar requirement of Visual C++ that __stdcall appear */
-/* after any "*"'s in the return value of a function while the */
-/* __declspec(dllexport) must appear before them. */
-/* -------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+ /* SHPAPI_CALL */
+ /* */
+ /* The following two macros are present to allow forcing */
+ /* various calling conventions on the Shapelib API. */
+ /* */
+ /* To force __stdcall conventions (needed to call Shapelib */
+ /* from Visual Basic and/or Delphi I believe) the makefile could */
+ /* be modified to define: */
+ /* */
+ /* /DSHPAPI_CALL=__stdcall */
+ /* */
+ /* If it is desired to force export of the Shapelib API without */
+ /* using the shapelib.def file, use the following definition. */
+ /* */
+ /* /DSHAPELIB_DLLEXPORT */
+ /* */
+ /* To get both at once it will be necessary to hack this */
+ /* include file to define: */
+ /* */
+ /* #define SHPAPI_CALL __declspec(dllexport) __stdcall */
+ /* #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall */
+ /* */
+ /* The complexity of the situation is partly caused by the */
+ /* peculiar requirement of Visual C++ that __stdcall appear */
+ /* after any "*"'s in the return value of a function while the */
+ /* __declspec(dllexport) must appear before them. */
+ /* -------------------------------------------------------------------- */
#ifdef SHAPELIB_DLLEXPORT
-# define SHPAPI_CALL __declspec(dllexport)
-# define SHPAPI_CALL1(x) __declspec(dllexport) x
+#define SHPAPI_CALL __declspec(dllexport)
+#define SHPAPI_CALL1(x) __declspec(dllexport) x
#endif
#ifndef SHPAPI_CALL
-# if defined(USE_GCC_VISIBILITY_FLAG)
-# define SHPAPI_CALL __attribute__ ((visibility("default")))
-# define SHPAPI_CALL1(x) __attribute__ ((visibility("default"))) x
-# else
-# define SHPAPI_CALL
-# endif
+#if defined(USE_GCC_VISIBILITY_FLAG)
+#define SHPAPI_CALL __attribute__((visibility("default")))
+#define SHPAPI_CALL1(x) __attribute__((visibility("default"))) x
+#else
+#define SHPAPI_CALL
#endif
-
-#ifndef SHPAPI_CALL1
-# define SHPAPI_CALL1(x) x SHPAPI_CALL
#endif
-/* -------------------------------------------------------------------- */
-/* Macros for controlling CVSID and ensuring they don't appear */
-/* as unreferenced variables resulting in lots of warnings. */
-/* -------------------------------------------------------------------- */
-#ifndef DISABLE_CVSID
-# if defined(__GNUC__) && __GNUC__ >= 4
-# define SHP_CVSID(string) static const char cpl_cvsid[] __attribute__((used)) = string;
-# else
-# define SHP_CVSID(string) static const char cpl_cvsid[] = string; \
-static const char *cvsid_aw() { return( cvsid_aw() ? NULL : cpl_cvsid ); }
-# endif
-#else
-# define SHP_CVSID(string)
+#ifndef SHPAPI_CALL1
+#define SHPAPI_CALL1(x) x SHPAPI_CALL
#endif
/* -------------------------------------------------------------------- */
@@ -273,204 +113,201 @@ static const char *cvsid_aw() { return( cvsid_aw() ? NULL : cpl_cvsid ); }
/* UTF-8 encoded filenames Unicode filenames */
/* -------------------------------------------------------------------- */
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
-# define SHPAPI_WINDOWS
-# define SHPAPI_UTF8_HOOKS
+#define SHPAPI_WINDOWS
+#define SHPAPI_UTF8_HOOKS
#endif
-/* -------------------------------------------------------------------- */
-/* IO/Error hook functions. */
-/* -------------------------------------------------------------------- */
-typedef int *SAFile;
+ /* -------------------------------------------------------------------- */
+ /* IO/Error hook functions. */
+ /* -------------------------------------------------------------------- */
+ typedef int *SAFile;
#ifndef SAOffset
-typedef unsigned long SAOffset;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ typedef unsigned __int64 SAOffset;
+#else
+ typedef unsigned long SAOffset;
+#endif
#endif
-typedef struct {
- SAFile (*FOpen) ( const char *filename, const char *access);
- SAOffset (*FRead) ( void *p, SAOffset size, SAOffset nmemb, SAFile file);
- SAOffset (*FWrite)( void *p, SAOffset size, SAOffset nmemb, SAFile file);
- SAOffset (*FSeek) ( SAFile file, SAOffset offset, int whence );
- SAOffset (*FTell) ( SAFile file );
- int (*FFlush)( SAFile file );
- int (*FClose)( SAFile file );
- int (*Remove) ( const char *filename );
-
- void (*Error) ( const char *message );
- double (*Atof) ( const char *str );
-} SAHooks;
-
-void SHPAPI_CALL SASetupDefaultHooks( SAHooks *psHooks );
+ typedef struct
+ {
+ SAFile (*FOpen)(const char *filename, const char *access,
+ void *pvUserData);
+ SAOffset (*FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file);
+ SAOffset (*FWrite)(const void *p, SAOffset size, SAOffset nmemb,
+ SAFile file);
+ SAOffset (*FSeek)(SAFile file, SAOffset offset, int whence);
+ SAOffset (*FTell)(SAFile file);
+ int (*FFlush)(SAFile file);
+ int (*FClose)(SAFile file);
+ int (*Remove)(const char *filename, void *pvUserData);
+
+ void (*Error)(const char *message);
+ double (*Atof)(const char *str);
+ void *pvUserData;
+ } SAHooks;
+
+ void SHPAPI_CALL SASetupDefaultHooks(SAHooks *psHooks);
#ifdef SHPAPI_UTF8_HOOKS
-void SHPAPI_CALL SASetupUtf8Hooks( SAHooks *psHooks );
+ void SHPAPI_CALL SASetupUtf8Hooks(SAHooks *psHooks);
#endif
-/************************************************************************/
-/* SHP Support. */
-/************************************************************************/
-typedef struct tagSHPObject SHPObject;
+ /************************************************************************/
+ /* SHP Support. */
+ /************************************************************************/
+ typedef struct tagSHPObject SHPObject;
-typedef struct
-{
- SAHooks sHooks;
+ typedef struct
+ {
+ SAHooks sHooks;
- SAFile fpSHP;
- SAFile fpSHX;
+ SAFile fpSHP;
+ SAFile fpSHX;
- int nShapeType; /* SHPT_* */
+ int nShapeType; /* SHPT_* */
- unsigned int nFileSize; /* SHP file */
+ unsigned int nFileSize; /* SHP file */
- int nRecords;
- int nMaxRecords;
- unsigned int*panRecOffset;
- unsigned int *panRecSize;
+ int nRecords;
+ int nMaxRecords;
+ unsigned int *panRecOffset;
+ unsigned int *panRecSize;
- double adBoundsMin[4];
- double adBoundsMax[4];
+ double adBoundsMin[4];
+ double adBoundsMax[4];
- int bUpdated;
+ int bUpdated;
- unsigned char *pabyRec;
- int nBufSize;
+ unsigned char *pabyRec;
+ int nBufSize;
- int bFastModeReadObject;
- unsigned char *pabyObjectBuf;
- int nObjectBufSize;
- SHPObject* psCachedObject;
-} SHPInfo;
+ int bFastModeReadObject;
+ unsigned char *pabyObjectBuf;
+ int nObjectBufSize;
+ SHPObject *psCachedObject;
+ } SHPInfo;
-typedef SHPInfo * SHPHandle;
+ typedef SHPInfo *SHPHandle;
/* -------------------------------------------------------------------- */
/* Shape types (nSHPType) */
/* -------------------------------------------------------------------- */
-#define SHPT_NULL 0
-#define SHPT_POINT 1
-#define SHPT_ARC 3
-#define SHPT_POLYGON 5
+#define SHPT_NULL 0
+#define SHPT_POINT 1
+#define SHPT_ARC 3
+#define SHPT_POLYGON 5
#define SHPT_MULTIPOINT 8
-#define SHPT_POINTZ 11
-#define SHPT_ARCZ 13
-#define SHPT_POLYGONZ 15
+#define SHPT_POINTZ 11
+#define SHPT_ARCZ 13
+#define SHPT_POLYGONZ 15
#define SHPT_MULTIPOINTZ 18
-#define SHPT_POINTM 21
-#define SHPT_ARCM 23
-#define SHPT_POLYGONM 25
+#define SHPT_POINTM 21
+#define SHPT_ARCM 23
+#define SHPT_POLYGONM 25
#define SHPT_MULTIPOINTM 28
#define SHPT_MULTIPATCH 31
-/* -------------------------------------------------------------------- */
-/* Part types - everything but SHPT_MULTIPATCH just uses */
-/* SHPP_RING. */
-/* -------------------------------------------------------------------- */
-
-#define SHPP_TRISTRIP 0
-#define SHPP_TRIFAN 1
-#define SHPP_OUTERRING 2
-#define SHPP_INNERRING 3
-#define SHPP_FIRSTRING 4
-#define SHPP_RING 5
-
-/* -------------------------------------------------------------------- */
-/* SHPObject - represents on shape (without attributes) read */
-/* from the .shp file. */
-/* -------------------------------------------------------------------- */
-struct tagSHPObject
-{
- int nSHPType;
-
- int nShapeId; /* -1 is unknown/unassigned */
-
- int nParts;
- int *panPartStart;
- int *panPartType;
-
- int nVertices;
- double *padfX;
- double *padfY;
- double *padfZ;
- double *padfM;
-
- double dfXMin;
- double dfYMin;
- double dfZMin;
- double dfMMin;
-
- double dfXMax;
- double dfYMax;
- double dfZMax;
- double dfMMax;
-
- int bMeasureIsUsed;
- int bFastModeReadObject;
-};
-
-/* -------------------------------------------------------------------- */
-/* SHP API Prototypes */
-/* -------------------------------------------------------------------- */
-
-/* If pszAccess is read-only, the fpSHX field of the returned structure */
-/* will be NULL as it is not necessary to keep the SHX file open */
-SHPHandle SHPAPI_CALL
- SHPOpen( const char * pszShapeFile, const char * pszAccess );
-SHPHandle SHPAPI_CALL
- SHPOpenLL( const char *pszShapeFile, const char *pszAccess,
- SAHooks *psHooks );
-SHPHandle SHPAPI_CALL
- SHPOpenLLEx( const char *pszShapeFile, const char *pszAccess,
- SAHooks *psHooks, int bRestoreSHX );
-
-int SHPAPI_CALL
- SHPRestoreSHX( const char *pszShapeFile, const char *pszAccess,
- SAHooks *psHooks );
-
-/* If setting bFastMode = TRUE, the content of SHPReadObject() is owned by the SHPHandle. */
-/* So you cannot have 2 valid instances of SHPReadObject() simultaneously. */
-/* The SHPObject padfZ and padfM members may be NULL depending on the geometry */
-/* type. It is illegal to free at hand any of the pointer members of the SHPObject structure */
-void SHPAPI_CALL SHPSetFastModeReadObject( SHPHandle hSHP, int bFastMode );
-
-SHPHandle SHPAPI_CALL
- SHPCreate( const char * pszShapeFile, int nShapeType );
-SHPHandle SHPAPI_CALL
- SHPCreateLL( const char * pszShapeFile, int nShapeType,
- SAHooks *psHooks );
-void SHPAPI_CALL
- SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
- double * padfMinBound, double * padfMaxBound );
-
-SHPObject SHPAPI_CALL1(*)
- SHPReadObject( SHPHandle hSHP, int iShape );
-int SHPAPI_CALL
- SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
-
-void SHPAPI_CALL
- SHPDestroyObject( SHPObject * psObject );
-void SHPAPI_CALL
- SHPComputeExtents( SHPObject * psObject );
-SHPObject SHPAPI_CALL1(*)
- SHPCreateObject( int nSHPType, int nShapeId, int nParts,
- const int * panPartStart, const int * panPartType,
- int nVertices,
- const double * padfX, const double * padfY,
- const double * padfZ, const double * padfM );
-SHPObject SHPAPI_CALL1(*)
- SHPCreateSimpleObject( int nSHPType, int nVertices,
- const double * padfX,
- const double * padfY,
- const double * padfZ );
-
-int SHPAPI_CALL
- SHPRewindObject( SHPHandle hSHP, SHPObject * psObject );
-
-void SHPAPI_CALL SHPClose( SHPHandle hSHP );
-void SHPAPI_CALL SHPWriteHeader( SHPHandle hSHP );
-
-const char SHPAPI_CALL1(*)
- SHPTypeName( int nSHPType );
-const char SHPAPI_CALL1(*)
- SHPPartTypeName( int nPartType );
+ /* -------------------------------------------------------------------- */
+ /* Part types - everything but SHPT_MULTIPATCH just uses */
+ /* SHPP_RING. */
+ /* -------------------------------------------------------------------- */
+
+#define SHPP_TRISTRIP 0
+#define SHPP_TRIFAN 1
+#define SHPP_OUTERRING 2
+#define SHPP_INNERRING 3
+#define SHPP_FIRSTRING 4
+#define SHPP_RING 5
+
+ /* -------------------------------------------------------------------- */
+ /* SHPObject - represents on shape (without attributes) read */
+ /* from the .shp file. */
+ /* -------------------------------------------------------------------- */
+ struct tagSHPObject
+ {
+ int nSHPType;
+
+ int nShapeId; /* -1 is unknown/unassigned */
+
+ int nParts;
+ int *panPartStart;
+ int *panPartType;
+
+ int nVertices;
+ double *padfX;
+ double *padfY;
+ double *padfZ;
+ double *padfM;
+
+ double dfXMin;
+ double dfYMin;
+ double dfZMin;
+ double dfMMin;
+
+ double dfXMax;
+ double dfYMax;
+ double dfZMax;
+ double dfMMax;
+
+ int bMeasureIsUsed;
+ int bFastModeReadObject;
+ };
+
+ /* -------------------------------------------------------------------- */
+ /* SHP API Prototypes */
+ /* -------------------------------------------------------------------- */
+
+ /* If pszAccess is read-only, the fpSHX field of the returned structure */
+ /* will be NULL as it is not necessary to keep the SHX file open */
+ SHPHandle SHPAPI_CALL SHPOpen(const char *pszShapeFile,
+ const char *pszAccess);
+ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszShapeFile,
+ const char *pszAccess,
+ const SAHooks *psHooks);
+ SHPHandle SHPAPI_CALL SHPOpenLLEx(const char *pszShapeFile,
+ const char *pszAccess,
+ const SAHooks *psHooks, int bRestoreSHX);
+
+ int SHPAPI_CALL SHPRestoreSHX(const char *pszShapeFile,
+ const char *pszAccess,
+ const SAHooks *psHooks);
+
+ /* If setting bFastMode = TRUE, the content of SHPReadObject() is owned by the SHPHandle. */
+ /* So you cannot have 2 valid instances of SHPReadObject() simultaneously. */
+ /* The SHPObject padfZ and padfM members may be NULL depending on the geometry */
+ /* type. It is illegal to free at hand any of the pointer members of the SHPObject structure */
+ void SHPAPI_CALL SHPSetFastModeReadObject(SHPHandle hSHP, int bFastMode);
+
+ SHPHandle SHPAPI_CALL SHPCreate(const char *pszShapeFile, int nShapeType);
+ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszShapeFile, int nShapeType,
+ const SAHooks *psHooks);
+ void SHPAPI_CALL SHPGetInfo(SHPHandle hSHP, int *pnEntities,
+ int *pnShapeType, double *padfMinBound,
+ double *padfMaxBound);
+
+ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle hSHP, int iShape);
+ int SHPAPI_CALL SHPWriteObject(SHPHandle hSHP, int iShape,
+ SHPObject *psObject);
+
+ void SHPAPI_CALL SHPDestroyObject(SHPObject *psObject);
+ void SHPAPI_CALL SHPComputeExtents(SHPObject *psObject);
+ SHPObject SHPAPI_CALL1(*)
+ SHPCreateObject(int nSHPType, int nShapeId, int nParts,
+ const int *panPartStart, const int *panPartType,
+ int nVertices, const double *padfX, const double *padfY,
+ const double *padfZ, const double *padfM);
+ SHPObject SHPAPI_CALL1(*)
+ SHPCreateSimpleObject(int nSHPType, int nVertices, const double *padfX,
+ const double *padfY, const double *padfZ);
+
+ int SHPAPI_CALL SHPRewindObject(SHPHandle hSHP, SHPObject *psObject);
+
+ void SHPAPI_CALL SHPClose(SHPHandle hSHP);
+ void SHPAPI_CALL SHPWriteHeader(SHPHandle hSHP);
+
+ const char SHPAPI_CALL1(*) SHPTypeName(int nSHPType);
+ const char SHPAPI_CALL1(*) SHPPartTypeName(int nPartType);
/* -------------------------------------------------------------------- */
/* Shape quadtree indexing API. */
@@ -482,271 +319,244 @@ const char SHPAPI_CALL1(*)
/* upper limit of tree levels for automatic estimation */
#define MAX_DEFAULT_TREE_DEPTH 12
-typedef struct shape_tree_node
-{
- /* region covered by this node */
- double adfBoundsMin[4];
- double adfBoundsMax[4];
+ typedef struct shape_tree_node
+ {
+ /* region covered by this node */
+ double adfBoundsMin[4];
+ double adfBoundsMax[4];
- /* list of shapes stored at this node. The papsShapeObj pointers
- or the whole list can be NULL */
- int nShapeCount;
- int *panShapeIds;
- SHPObject **papsShapeObj;
+ /* list of shapes stored at this node. The papsShapeObj pointers
+ or the whole list can be NULL */
+ int nShapeCount;
+ int *panShapeIds;
+ SHPObject **papsShapeObj;
- int nSubNodes;
- struct shape_tree_node *apsSubNode[MAX_SUBNODE];
+ int nSubNodes;
+ struct shape_tree_node *apsSubNode[MAX_SUBNODE];
-} SHPTreeNode;
+ } SHPTreeNode;
-typedef struct
-{
- SHPHandle hSHP;
+ typedef struct
+ {
+ SHPHandle hSHP;
- int nMaxDepth;
- int nDimension;
- int nTotalCount;
+ int nMaxDepth;
+ int nDimension;
+ int nTotalCount;
- SHPTreeNode *psRoot;
-} SHPTree;
+ SHPTreeNode *psRoot;
+ } SHPTree;
-SHPTree SHPAPI_CALL1(*)
- SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
- double *padfBoundsMin, double *padfBoundsMax );
-void SHPAPI_CALL
- SHPDestroyTree( SHPTree * hTree );
+ SHPTree SHPAPI_CALL1(*)
+ SHPCreateTree(SHPHandle hSHP, int nDimension, int nMaxDepth,
+ const double *padfBoundsMin, const double *padfBoundsMax);
+ void SHPAPI_CALL SHPDestroyTree(SHPTree *hTree);
-int SHPAPI_CALL
- SHPWriteTree( SHPTree *hTree, const char * pszFilename );
+ int SHPAPI_CALL SHPWriteTree(SHPTree *hTree, const char *pszFilename);
-int SHPAPI_CALL
- SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject );
-int SHPAPI_CALL
- SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId );
+ int SHPAPI_CALL SHPTreeAddShapeId(SHPTree *hTree, SHPObject *psObject);
+ int SHPAPI_CALL SHPTreeRemoveShapeId(SHPTree *hTree, int nShapeId);
-void SHPAPI_CALL
- SHPTreeTrimExtraNodes( SHPTree * hTree );
+ void SHPAPI_CALL SHPTreeTrimExtraNodes(SHPTree *hTree);
-int SHPAPI_CALL1(*)
- SHPTreeFindLikelyShapes( SHPTree * hTree,
- double * padfBoundsMin,
- double * padfBoundsMax,
- int * );
-int SHPAPI_CALL
- SHPCheckBoundsOverlap( double *, double *, double *, double *, int );
+ int SHPAPI_CALL1(*)
+ SHPTreeFindLikelyShapes(SHPTree *hTree, double *padfBoundsMin,
+ double *padfBoundsMax, int *);
+ int SHPAPI_CALL SHPCheckBoundsOverlap(const double *, const double *,
+ const double *, const double *, int);
-int SHPAPI_CALL1(*)
-SHPSearchDiskTree( FILE *fp,
- double *padfBoundsMin, double *padfBoundsMax,
- int *pnShapeCount );
+ int SHPAPI_CALL1(*)
+ SHPSearchDiskTree(FILE *fp, double *padfBoundsMin,
+ double *padfBoundsMax, int *pnShapeCount);
-typedef struct SHPDiskTreeInfo* SHPTreeDiskHandle;
+ typedef struct SHPDiskTreeInfo *SHPTreeDiskHandle;
-SHPTreeDiskHandle SHPAPI_CALL
- SHPOpenDiskTree( const char* pszQIXFilename,
- SAHooks *psHooks );
+ SHPTreeDiskHandle SHPAPI_CALL SHPOpenDiskTree(const char *pszQIXFilename,
+ const SAHooks *psHooks);
-void SHPAPI_CALL
- SHPCloseDiskTree( SHPTreeDiskHandle hDiskTree );
+ void SHPAPI_CALL SHPCloseDiskTree(SHPTreeDiskHandle hDiskTree);
-int SHPAPI_CALL1(*)
-SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree,
- double *padfBoundsMin, double *padfBoundsMax,
- int *pnShapeCount );
+ int SHPAPI_CALL1(*)
+ SHPSearchDiskTreeEx(SHPTreeDiskHandle hDiskTree, double *padfBoundsMin,
+ double *padfBoundsMax, int *pnShapeCount);
-int SHPAPI_CALL
- SHPWriteTreeLL(SHPTree *hTree, const char *pszFilename, SAHooks *psHooks );
+ int SHPAPI_CALL SHPWriteTreeLL(SHPTree *hTree, const char *pszFilename,
+ const SAHooks *psHooks);
-/* -------------------------------------------------------------------- */
-/* SBN Search API */
-/* -------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+ /* SBN Search API */
+ /* -------------------------------------------------------------------- */
-typedef struct SBNSearchInfo* SBNSearchHandle;
+ typedef struct SBNSearchInfo *SBNSearchHandle;
-SBNSearchHandle SHPAPI_CALL
- SBNOpenDiskTree( const char* pszSBNFilename,
- SAHooks *psHooks );
+ SBNSearchHandle SHPAPI_CALL SBNOpenDiskTree(const char *pszSBNFilename,
+ const SAHooks *psHooks);
-void SHPAPI_CALL
- SBNCloseDiskTree( SBNSearchHandle hSBN );
+ void SHPAPI_CALL SBNCloseDiskTree(SBNSearchHandle hSBN);
-int SHPAPI_CALL1(*)
-SBNSearchDiskTree( SBNSearchHandle hSBN,
- double *padfBoundsMin, double *padfBoundsMax,
- int *pnShapeCount );
+ int SHPAPI_CALL1(*)
+ SBNSearchDiskTree(SBNSearchHandle hSBN, const double *padfBoundsMin,
+ const double *padfBoundsMax, int *pnShapeCount);
-int SHPAPI_CALL1(*)
-SBNSearchDiskTreeInteger( SBNSearchHandle hSBN,
- int bMinX, int bMinY, int bMaxX, int bMaxY,
- int *pnShapeCount );
+ int SHPAPI_CALL1(*)
+ SBNSearchDiskTreeInteger(SBNSearchHandle hSBN, int bMinX, int bMinY,
+ int bMaxX, int bMaxY, int *pnShapeCount);
-void SHPAPI_CALL SBNSearchFreeIds( int* panShapeId );
+ void SHPAPI_CALL SBNSearchFreeIds(int *panShapeId);
-/************************************************************************/
-/* DBF Support. */
-/************************************************************************/
-typedef struct
-{
- SAHooks sHooks;
+ /************************************************************************/
+ /* DBF Support. */
+ /************************************************************************/
+ typedef struct
+ {
+ SAHooks sHooks;
- SAFile fp;
+ SAFile fp;
- int nRecords;
+ int nRecords;
- int nRecordLength; /* Must fit on uint16 */
- int nHeaderLength; /* File header length (32) + field
- descriptor length + spare space.
- Must fit on uint16 */
- int nFields;
- int *panFieldOffset;
- int *panFieldSize;
- int *panFieldDecimals;
- char *pachFieldType;
+ int nRecordLength; /* Must fit on uint16 */
+ int nHeaderLength; /* File header length (32) + field
+ descriptor length + spare space.
+ Must fit on uint16 */
+ int nFields;
+ int *panFieldOffset;
+ int *panFieldSize;
+ int *panFieldDecimals;
+ char *pachFieldType;
- char *pszHeader; /* Field descriptors */
+ char *pszHeader; /* Field descriptors */
- int nCurrentRecord;
- int bCurrentRecordModified;
- char *pszCurrentRecord;
+ int nCurrentRecord;
+ int bCurrentRecordModified;
+ char *pszCurrentRecord;
- int nWorkFieldLength;
- char *pszWorkField;
+ int nWorkFieldLength;
+ char *pszWorkField;
- int bNoHeader;
- int bUpdated;
+ int bNoHeader;
+ int bUpdated;
- union
- {
- double dfDoubleField;
- int nIntField;
- } fieldValue;
+ union
+ {
+ double dfDoubleField;
+ int nIntField;
+ } fieldValue;
+
+ int iLanguageDriver;
+ char *pszCodePage;
- int iLanguageDriver;
- char *pszCodePage;
+ int nUpdateYearSince1900; /* 0-255 */
+ int nUpdateMonth; /* 1-12 */
+ int nUpdateDay; /* 1-31 */
- int nUpdateYearSince1900; /* 0-255 */
- int nUpdateMonth; /* 1-12 */
- int nUpdateDay; /* 1-31 */
+ int bWriteEndOfFileChar; /* defaults to TRUE */
- int bWriteEndOfFileChar; /* defaults to TRUE */
-} DBFInfo;
+ int bRequireNextWriteSeek;
+ } DBFInfo;
-typedef DBFInfo * DBFHandle;
+ typedef DBFInfo *DBFHandle;
-typedef enum {
- FTString,
- FTInteger,
- FTDouble,
- FTLogical,
- FTDate,
- FTInvalid
-} DBFFieldType;
+ typedef enum
+ {
+ FTString,
+ FTInteger,
+ FTDouble,
+ FTLogical,
+ FTDate,
+ FTInvalid
+ } DBFFieldType;
/* Field descriptor/header size */
-#define XBASE_FLDHDR_SZ 32
+#define XBASE_FLDHDR_SZ 32
/* Shapelib read up to 11 characters, even if only 10 should normally be used */
-#define XBASE_FLDNAME_LEN_READ 11
+#define XBASE_FLDNAME_LEN_READ 11
/* On writing, we limit to 10 characters */
#define XBASE_FLDNAME_LEN_WRITE 10
/* Normally only 254 characters should be used. We tolerate 255 historically */
-#define XBASE_FLD_MAX_WIDTH 255
-
-DBFHandle SHPAPI_CALL
- DBFOpen( const char * pszDBFFile, const char * pszAccess );
-DBFHandle SHPAPI_CALL
- DBFOpenLL( const char * pszDBFFile, const char * pszAccess,
- SAHooks *psHooks );
-DBFHandle SHPAPI_CALL
- DBFCreate( const char * pszDBFFile );
-DBFHandle SHPAPI_CALL
- DBFCreateEx( const char * pszDBFFile, const char * pszCodePage );
-DBFHandle SHPAPI_CALL
- DBFCreateLL( const char * pszDBFFile, const char * pszCodePage, SAHooks *psHooks );
-
-int SHPAPI_CALL
- DBFGetFieldCount( DBFHandle psDBF );
-int SHPAPI_CALL
- DBFGetRecordCount( DBFHandle psDBF );
-int SHPAPI_CALL
- DBFAddField( DBFHandle hDBF, const char * pszFieldName,
- DBFFieldType eType, int nWidth, int nDecimals );
-
-int SHPAPI_CALL
- DBFAddNativeFieldType( DBFHandle hDBF, const char * pszFieldName,
- char chType, int nWidth, int nDecimals );
-
-int SHPAPI_CALL
- DBFDeleteField( DBFHandle hDBF, int iField );
-
-int SHPAPI_CALL
- DBFReorderFields( DBFHandle psDBF, int* panMap );
-
-int SHPAPI_CALL
- DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
- char chType, int nWidth, int nDecimals );
-
-DBFFieldType SHPAPI_CALL
- DBFGetFieldInfo( DBFHandle psDBF, int iField,
- char * pszFieldName, int * pnWidth, int * pnDecimals );
-
-int SHPAPI_CALL
- DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName);
-
-int SHPAPI_CALL
- DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
-double SHPAPI_CALL
- DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
-const char SHPAPI_CALL1(*)
- DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
-const char SHPAPI_CALL1(*)
- DBFReadLogicalAttribute( DBFHandle hDBF, int iShape, int iField );
-int SHPAPI_CALL
- DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
-
-int SHPAPI_CALL
- DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField,
- int nFieldValue );
-int SHPAPI_CALL
- DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
- double dFieldValue );
-int SHPAPI_CALL
- DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
- const char * pszFieldValue );
-int SHPAPI_CALL
- DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );
-
-int SHPAPI_CALL
- DBFWriteLogicalAttribute( DBFHandle hDBF, int iShape, int iField,
- const char lFieldValue);
-int SHPAPI_CALL
- DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
- void * pValue );
-const char SHPAPI_CALL1(*)
- DBFReadTuple(DBFHandle psDBF, int hEntity );
-int SHPAPI_CALL
- DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple );
-
-int SHPAPI_CALL DBFIsRecordDeleted( DBFHandle psDBF, int iShape );
-int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape,
- int bIsDeleted );
-
-DBFHandle SHPAPI_CALL
- DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );
-
-void SHPAPI_CALL
- DBFClose( DBFHandle hDBF );
-void SHPAPI_CALL
- DBFUpdateHeader( DBFHandle hDBF );
-char SHPAPI_CALL
- DBFGetNativeFieldType( DBFHandle hDBF, int iField );
-
-const char SHPAPI_CALL1(*)
- DBFGetCodePage(DBFHandle psDBF );
-
-void SHPAPI_CALL
- DBFSetLastModifiedDate( DBFHandle psDBF, int nYYSince1900, int nMM, int nDD );
-
-void SHPAPI_CALL DBFSetWriteEndOfFileChar( DBFHandle psDBF, int bWriteFlag );
+#define XBASE_FLD_MAX_WIDTH 255
+
+ DBFHandle SHPAPI_CALL DBFOpen(const char *pszDBFFile,
+ const char *pszAccess);
+ DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszDBFFile,
+ const char *pszAccess,
+ const SAHooks *psHooks);
+ DBFHandle SHPAPI_CALL DBFCreate(const char *pszDBFFile);
+ DBFHandle SHPAPI_CALL DBFCreateEx(const char *pszDBFFile,
+ const char *pszCodePage);
+ DBFHandle SHPAPI_CALL DBFCreateLL(const char *pszDBFFile,
+ const char *pszCodePage,
+ const SAHooks *psHooks);
+
+ int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF);
+ int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF);
+ int SHPAPI_CALL DBFAddField(DBFHandle hDBF, const char *pszFieldName,
+ DBFFieldType eType, int nWidth, int nDecimals);
+
+ int SHPAPI_CALL DBFAddNativeFieldType(DBFHandle hDBF,
+ const char *pszFieldName, char chType,
+ int nWidth, int nDecimals);
+
+ int SHPAPI_CALL DBFDeleteField(DBFHandle hDBF, int iField);
+
+ int SHPAPI_CALL DBFReorderFields(DBFHandle psDBF, const int *panMap);
+
+ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField,
+ const char *pszFieldName, char chType,
+ int nWidth, int nDecimals);
+
+ DBFFieldType SHPAPI_CALL DBFGetFieldInfo(DBFHandle psDBF, int iField,
+ char *pszFieldName, int *pnWidth,
+ int *pnDecimals);
+
+ int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName);
+
+ int SHPAPI_CALL DBFReadIntegerAttribute(DBFHandle hDBF, int iShape,
+ int iField);
+ double SHPAPI_CALL DBFReadDoubleAttribute(DBFHandle hDBF, int iShape,
+ int iField);
+ const char SHPAPI_CALL1(*)
+ DBFReadStringAttribute(DBFHandle hDBF, int iShape, int iField);
+ const char SHPAPI_CALL1(*)
+ DBFReadLogicalAttribute(DBFHandle hDBF, int iShape, int iField);
+ int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle hDBF, int iShape, int iField);
+
+ int SHPAPI_CALL DBFWriteIntegerAttribute(DBFHandle hDBF, int iShape,
+ int iField, int nFieldValue);
+ int SHPAPI_CALL DBFWriteDoubleAttribute(DBFHandle hDBF, int iShape,
+ int iField, double dFieldValue);
+ int SHPAPI_CALL DBFWriteStringAttribute(DBFHandle hDBF, int iShape,
+ int iField,
+ const char *pszFieldValue);
+ int SHPAPI_CALL DBFWriteNULLAttribute(DBFHandle hDBF, int iShape,
+ int iField);
+
+ int SHPAPI_CALL DBFWriteLogicalAttribute(DBFHandle hDBF, int iShape,
+ int iField,
+ const char lFieldValue);
+ int SHPAPI_CALL DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity,
+ int iField, const void *pValue);
+ const char SHPAPI_CALL1(*) DBFReadTuple(DBFHandle psDBF, int hEntity);
+ int SHPAPI_CALL DBFWriteTuple(DBFHandle psDBF, int hEntity,
+ const void *pRawTuple);
+
+ int SHPAPI_CALL DBFIsRecordDeleted(DBFHandle psDBF, int iShape);
+ int SHPAPI_CALL DBFMarkRecordDeleted(DBFHandle psDBF, int iShape,
+ int bIsDeleted);
+
+ DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF,
+ const char *pszFilename);
+
+ void SHPAPI_CALL DBFClose(DBFHandle hDBF);
+ void SHPAPI_CALL DBFUpdateHeader(DBFHandle hDBF);
+ char SHPAPI_CALL DBFGetNativeFieldType(DBFHandle hDBF, int iField);
+
+ const char SHPAPI_CALL1(*) DBFGetCodePage(DBFHandle psDBF);
+
+ void SHPAPI_CALL DBFSetLastModifiedDate(DBFHandle psDBF, int nYYSince1900,
+ int nMM, int nDD);
+
+ void SHPAPI_CALL DBFSetWriteEndOfFileChar(DBFHandle psDBF, int bWriteFlag);
#ifdef __cplusplus
}
diff --git a/shapelib/shapelib.html b/shapelib/shapelib.html
index fa81f91aa..b3d72ba5a 100644
--- a/shapelib/shapelib.html
+++ b/shapelib/shapelib.html
@@ -27,20 +27,19 @@ and the associated attribute file (.dbf).
What is a Shapefile?
If you don't know, you probably don't need this library. The Shapefile
-format is a working and interchange format promulagated by
+format is a working and interchange format promulgated by
ESRI for simple vector data with attributes.
-An excellent white paper on the shapefile format
-is available from ESRI,
-but it is .pdf format, so you will need Adobe Acrobat to browse it.
+An excellent white paper
+on the shapefile format is available from ESRI.
The file format actually consists of three files.
XXX.shp - holds the actual vertices.
XXX.shx - hold index data pointing to the structures in the .shp file.
-XXX.dbf - holds the attributes in xBase (dBase) format.
+XXX.dbf - holds the attributes in xBase (dBase) format.
Download
@@ -48,27 +47,22 @@ XXX.dbf - holds the attributes in xBase (dBase) format.
Source code, and some other odds and ends can be downloaded from
http://download.osgeo.org/shapelib.
-Shapelib is available for anonymous CVS access:
-
-
- cvs -d :pserver:cvsanon@cvs.maptools.org:/cvs/maptools/cvsroot login
- Password: (hit enter)
- cvs -d :pserver:cvsanon@cvs.maptools.org:/cvs/maptools/cvsroot co shapelib
-
+Shapelib repository is at
+https://github.com/OSGeo/shapelib
Bugs, Maintainance and Support
-This library is maintained by Frank
-Warmerdam. Please send me bug reports, patches and suggestions for the
+This library is maintained by Frank
+Warmerdam. Please send me bug reports, patches and suggestions for the
library via the maptools.org Bugzilla. Shapelib bugs can also be
queried.
-Shapelib is hosted at
+Shapelib is hosted at
shapelib.maptools.org. A mailing
-list for discussion of how to use shapelib, and announcing new releases
-is
-available. To get notification of new releases of Shapelib subscribe to
+list for discussion of how to use shapelib, and announcing new releases
+is
+available. To get notification of new releases of Shapelib subscribe to
the project mailing list at https://lists.osgeo.org/pipermail/shapelib/.
Credits
@@ -78,7 +72,7 @@ contributors to Shapelib are lost in pre-history.
- Bill Miller (NY-DOT) for shputils.c
-
- Carl Anderson for the contents of the contrib directory, and
+
- Carl Anderson for the contents of the contrib directory, and
the "tuple" additions to dbfopen.c.
- Andrea Giacomelli for patches for dbfopen.c.
- Doug Matthews for portability improvements.
@@ -96,10 +90,10 @@ who hosted shapelib for years.
In Memorium
I would like to dedicate Shapelib to the memory of Sol Katz. While I never
-met him in person, his generous contributions to the GIS community took
+met him in person, his generous contributions to the GIS community took
many forms, including free distribution of a variety of GIS translators
-with source. The fact that he used this Shapelib in some of his utilities,
-and thanked me was a great encouragement to me. I hope I can do his memory
+with source. The fact that he used this Shapelib in some of his utilities,
+and thanked me was a great encouragement to me. I hope I can do his memory
honour by trying to contribute in a similar fashion.
Portability
@@ -114,7 +108,7 @@ such as MSDOS.
The shputils.c module is contributed, and may not take the same approach
to portability as the rest of the package.
-On Linux, and most unix systems it should be possible to build and
+On Linux, and most unix systems it should be possible to build and
install shapefile support as a shared library using the "lib" and "lib_install"
targets of the Makefile. Note that this Makefile doesn't use autoconf
mechanisms and will generally require some hand tailoring for your environment.
@@ -123,11 +117,11 @@ mechanisms and will generally require some hand tailoring for your environment.
-- You can't modify the vertices of existing structures (though you
- can update the attributes of existing structures, and create new
+
- You can't modify the vertices of existing structures (though you
+ can update the attributes of existing structures, and create new
structures).
-
- Not written in such a way as to be particularly fast. This is
+
- Not written in such a way as to be particularly fast. This is
particularly true of the 1.2 API. For applications more concerned with
speed it may be worth using the V1.1 API.
@@ -159,32 +153,32 @@ files through appropriate use of the DBF and SHP APIs.
- Language ID / Code Page mappings
-
- Shapelib is used within the multiformat
-OGR library. If you are looking for a
+
- Shapelib is used within the multiformat
+OGR library. If you are looking for a
high level C++ library with support for many geospatial vector formats you
might want to check it out.
-
- Ari Jolma has produced an initial perl binding on top of shapelib,
-which can be found at CPAN as Geo::ShapeFile under the
+
- Ari Jolma has produced an initial perl binding on top of shapelib,
+which can be found at CPAN as Geo::ShapeFile under the
Geo module.
-
- Bernhard Herzog has produced python bindings for Shapelib with
-SWIG, available at http://ftp.intevation.de/users/bh/pyshapelib. A new version not using swig is
+
- Bernhard Herzog has produced python bindings for Shapelib with
+SWIG, available at http://ftp.intevation.de/users/bh/pyshapelib. A new version not using swig is
available as part of Thuban.
- Delphi
bindings for Shapelib courtesy of Alexander Weidauer.
-
- Miguel Filgueiras has implemented
+
- Miguel Filgueiras has implemented
Tcl bindings for Shapelib
as part of GPSMan.
- David Gancarz has implemented a Microsoft
.NET wrapper for
-Shapelib. An example of using shapelib with VB6 is also icluded in the .NET wrapper project file.
+Shapelib. An example of using shapelib with VB6 is also included in the .NET wrapper project file.
-
- Andrey Hristov (php at hristov dot com) has developed a PHP extension
+
- Andrey Hristov (php at hristov dot com) has developed a PHP extension
based on Shapelib. It can be found in CVS at http://cvs.php.net/pecl/shp.
- Toyoda Eizi has developed Ruby bindings found at
@@ -200,11 +194,11 @@ files. He maintains a web page
- Tom Russo has implemented a shpcs2cs program, which reprojects shapefiles
using arguments similar to the PROJ.4 cs2cs program including datum conversion.
-Use as an alternate to the contrib/shpproj which doesn't do datums. It is
+Use as an alternate to the contrib/shpproj which doesn't do datums. It is
available at the bottom of Tom's Xastir Shapefile Resources page.
-
-
-Andrew Williamson's
+
-
+Andrew Williamson's
Useful
Scripts and Stuff page for ArcView, which includes ShapeChecker.
@@ -216,13 +210,13 @@ VB access to Shapefiles. Also available ShapeFile Read/Write OCX is another option for Visual Basic programmers.
-
- Isovist Analyst is a sort-of-free isovist generating extension for
+
- Isovist Analyst is a sort-of-free isovist generating extension for
ArcView using shapelib.
-
- shpdiff utility
+
- shpdiff utility
by Bryce Nesbitt.
-
- Aequometer: a program for
+
- Aequometer: a program for
MS Excel to calculate the area of polygons and export as shapefiles.
diff --git a/shapelib/shp_api.html b/shapelib/shp_api.html
index d773e3e56..55900bd6f 100644
--- a/shapelib/shp_api.html
+++ b/shapelib/shp_api.html
@@ -31,7 +31,7 @@ a Shapefile must be of the same type (with the exception of NULL shapes).
3D Shape Types (may include "measure" values for vertices):
- #define SHPT_POINTZ 11
+ #define SHPT_POINTZ 11
#define SHPT_ARCZ 13
#define SHPT_POLYGONZ 15
#define SHPT_MULTIPOINTZ 18
@@ -66,9 +66,9 @@ should be disposed of with SHPDestroyObject().
int nParts; # of Parts (0 implies single part with no info)
int *panPartStart; Start Vertex of part
int *panPartType; Part Type (SHPP_RING if not SHPT_MULTIPATCH)
-
- int nVertices; Vertex list
- double *padfX;
+
+ int nVertices; Vertex list
+ double *padfX;
double *padfY;
double *padfZ; (all zero if not provided)
double *padfM; (all zero if not provided)
@@ -97,15 +97,15 @@ SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );
just be the path plus the basename of the pair.
pszAccess: The fopen() style access string. At this time only
- "rb" (read-only binary) and "rb+" (read/write binary)
+ "rb" (read-only binary) and "rb+" (read/write binary)
should be used.
The SHPOpen() function should be used to establish access to the two files
- for accessing vertices (.shp and .shx). Note that both files have to
+ for accessing vertices (.shp and .shx). Note that both files have to
be in the indicated directory, and must have the expected extensions in
- lower case. The returned SHPHandle is passed to other access functions,
- and SHPClose() should be invoked to recover resources, and flush changes
+ lower case. The returned SHPHandle is passed to other access functions,
+ and SHPClose() should be invoked to recover resources, and flush changes
to disk when complete.
@@ -116,7 +116,7 @@ SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );
void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
double * padfMinBound, double * padfMaxBound );
- hSHP: The handle previously returned by SHPOpen()
+ hSHP: The handle previously returned by SHPOpen()
or SHPCreate().
pnEntities: A pointer to an integer into which the number of
@@ -124,20 +124,20 @@ void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
pnShapetype: A pointer to an integer into which the shapetype
of this file should be placed. Shapefiles may contain
- either SHPT_POINT, SHPT_ARC, SHPT_POLYGON or
+ either SHPT_POINT, SHPT_ARC, SHPT_POLYGON or
SHPT_MULTIPOINT entities. This may be NULL.
padfMinBound: The X, Y, Z and M minimum values will be placed into
this four entry array. This may be NULL.
-
+
padfMaxBound: The X, Y, Z and M maximum values will be placed into
this four entry array. This may be NULL.
The SHPGetInfo() function retrieves various information about shapefile
- as a whole. The bounds are read from the file header, and may be
+ as a whole. The bounds are read from the file header, and may be
inaccurate if the file was improperly generated. - +
SHPObject *SHPReadObject( SHPHandle hSHP, int iShape ); - hSHP: The handle previously returned by SHPOpen() + hSHP: The handle previously returned by SHPOpen() or SHPCreate(). - iShape: The entity number of the shape to read. Entity + iShape: The entity number of the shape to read. Entity numbers are between 0 and nEntities-1 (as returned by SHPGetInfo()).@@ -156,7 +156,7 @@ SHPObject *SHPReadObject( SHPHandle hSHP, int iShape ); The SHPReadObject() call is used to read a single structure, or entity from the shapefile. See the definition of the SHPObject structure for detailed information on fields of a SHPObject. SHPObject's returned from - SHPReadObject() should be deallocated with SHPDestroyShape(). + SHPReadObject() should be deallocated with SHPDestroyShape(). SHPReadObject() will return NULL if an illegal iShape value is requested.
Note that the bounds placed into the SHPObject are those read from the @@ -175,7 +175,7 @@ SHPObject *SHPReadObject( SHPHandle hSHP, int iShape );
void SHPClose( SHPHandle hSHP ); - hSHP: The handle previously returned by SHPOpen() + hSHP: The handle previously returned by SHPOpen() or SHPCreate().@@ -196,7 +196,7 @@ SHPHandle SHPCreate( const char * pszShapeFile, int nShapeType ); just be the path plus the basename of the pair. nShapeType: The type of shapes to be stored in the newly created - file. It may be either SHPT_POINT, SHPT_ARC, + file. It may be either SHPT_POINT, SHPT_ARC, SHPT_POLYGON or SHPT_MULTIPOINT. @@ -208,15 +208,15 @@ SHPHandle SHPCreate( const char * pszShapeFile, int nShapeType );
-SHPObject *
- SHPCreateSimpleObject( int nSHPType, int nVertices,
+SHPObject *
+ SHPCreateSimpleObject( int nSHPType, int nVertices,
double *padfX, double * padfY, double *padfZ, );
nSHPType: The SHPT_ type of the object to be created, such
as SHPT_POINT, or SHPT_POLYGON.
-
- nVertices: The number of vertices being passed in padfX,
- padfY, and padfZ.
+
+ nVertices: The number of vertices being passed in padfX,
+ padfY, and padfZ.
padfX: An array of nVertices X coordinates of the vertices
for this object.
@@ -229,7 +229,7 @@ SHPObject *
they are all assumed to be zero.
- The SHPCreateSimpleObject() allows for the convenient creation of
+ The SHPCreateSimpleObject() allows for the convenient creation of
simple objects. This is normally used so that the SHPObject can be
passed to SHPWriteObject() to write it to the file. The simple object
creation API assumes an M (measure) value of zero for each vertex. For
@@ -240,7 +240,7 @@ SHPObject *
SHPDestroyObject() function should be used to free resources associated with
an object allocated with SHPCreateSimpleObject(). - This function computes a bounding box for the SHPObject from the given + This function computes a bounding box for the SHPObject from the given vertices.
@@ -248,10 +248,10 @@ SHPObject *
-SHPObject *
+SHPObject *
SHPCreateObject( int nSHPType, int iShape,
int nParts, int * panPartStart, int * panPartType,
- int nVertices, double *padfX, double * padfY,
+ int nVertices, double *padfX, double * padfY,
double *padfZ, double *padfM );
nSHPType: The SHPT_ type of the object to be created, such
@@ -260,19 +260,19 @@ SHPObject *
iShape: The shapeid to be recorded with this shape.
nParts: The number of parts for this object. If this is
- zero for ARC, or POLYGON type objects, a single
+ zero for ARC, or POLYGON type objects, a single
zero valued part will be created internally.
-
+
panPartStart: The list of zero based start vertices for the rings
(parts) in this object. The first should always be
zero. This may be NULL if nParts is 0.
-
+
panPartType: The type of each of the parts. This is only meaningful
for MULTIPATCH files. For all other cases this may
be NULL, and will be assumed to be SHPP_RING.
-
- nVertices: The number of vertices being passed in padfX,
- padfY, and padfZ.
+
+ nVertices: The number of vertices being passed in padfX,
+ padfY, and padfZ.
padfX: An array of nVertices X coordinates of the vertices
for this object.
@@ -284,19 +284,19 @@ SHPObject *
for this object. This may be NULL in which case
they are all assumed to be zero.
- padfM: An array of nVertices M (measure values) of the
- vertices for this object. This may be NULL in which
+ padfM: An array of nVertices M (measure values) of the
+ vertices for this object. This may be NULL in which
case they are all assumed to be zero.
- The SHPCreateSimpleObject() allows for the creation of objects (shapes).
- This is normally used so that the SHPObject can be passed to
+ The SHPCreateSimpleObject() allows for the creation of objects (shapes).
+ This is normally used so that the SHPObject can be passed to
SHPWriteObject() to write it to the file. - The SHPDestroyObject() function should be used to free resources associated + The SHPDestroyObject() function should be used to free resources associated with an object allocated with SHPCreateObject().
- This function computes a bounding box for the SHPObject from the given + This function computes a bounding box for the SHPObject from the given vertices.
@@ -308,9 +308,9 @@ void SHPComputeExtents( SHPObject * psObject ); psObject: An existing shape object to be updated in place. - + This function will recompute the extents of this shape, replacing the - existing values of the dfXMin, dfYMin, dfZMin, dfMMin, dfXMax, dfYMax, + existing values of the dfXMin, dfYMin, dfZMin, dfMMin, dfXMax, dfYMax, dfZMax, and dfMMax values based on the current set of vertices for the shape. This function is automatically called by SHPCreateObject() but if the vertices of an existing object are altered it should be called again @@ -323,14 +323,14 @@ void SHPComputeExtents( SHPObject * psObject );
int SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject *psObject );
- hSHP: The handle previously returned by SHPOpen("r+")
+ hSHP: The handle previously returned by SHPOpen("r+")
or SHPCreate().
iShape: The entity number of the shape to write. A value of
- -1 should be used for new shapes.
+ -1 should be used for new shapes.
psObject: The shape to write to the file. This should have
- been created with SHPCreateObject(), or
+ been created with SHPCreateObject(), or
SHPCreateSimpleObject().
@@ -368,7 +368,7 @@ int SHPRewindObject( SHPHandle hSHP, SHPObject *psObject );
This function will reverse any rings necessary in order to enforce the
shapefile restrictions on the required order of inner and outer rings in
the Shapefile specification. It returns TRUE if a change is made and FALSE
- if no change is made. Only polygon objects will be affected though any
+ if no change is made. Only polygon objects will be affected though any
object may be passed.
diff --git a/shapelib/shpopen.c b/shapelib/shpopen.c
index 2fcff96da..2cf982ddf 100644
--- a/shapelib/shpopen.c
+++ b/shapelib/shpopen.c
@@ -1,5 +1,4 @@
/******************************************************************************
- * $Id: shpopen.c,v 1.78 2019-02-28 15:55:23 erouault Exp $
*
* Project: Shapelib
* Purpose: Implementation of core Shapefile read/write functions.
@@ -7,367 +6,72 @@
*
******************************************************************************
* Copyright (c) 1999, 2001, Frank Warmerdam
- * Copyright (c) 2011-2013, Even Rouault